Skip to content

Commit

Permalink
[php] rename local vars with the same names as super global vars (fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
RealyUniqueName committed Oct 20, 2020
1 parent 7522eb2 commit 8c0b13c
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 9 deletions.
1 change: 1 addition & 0 deletions extra/CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

jvm : fixed equality checks for `Null<Float>` and `Null<Int>` (#9897)
hl : fixed crash if a thread finishes without invoking `sendMessage`/`readMessage` (#9920)
php : fixed local vars with certain names (_SERVER, _GET etc) overriding super global values (#9924)

2020-09-11 4.1.4:

Expand Down
27 changes: 18 additions & 9 deletions src/generators/genphp7.ml
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,15 @@ let is_native_array_type t = match follow t with TAbstract ({ a_path = tp }, _)
*)
let get_real_name name = if is_keyword name then name ^ "_hx" else name

(**
Returns local variable name free of risk to collide with superglobals like $_SERVER or $_GET
*)
let vname name =
match name with
| "GLOBALS" | "_SERVER" | "_GET" | "_POST" | "_FILES" | "_COOKIE"
| "_SESSION" | "_REQUEST" | "_ENV" -> name ^ "_hx_"
| _ -> name

(**
If `path` contains some reserved in PHP words, they will be replaced with allowed words.
*)
Expand Down Expand Up @@ -1546,8 +1555,8 @@ class code_writer (ctx:php_generator_context) hx_type_path php_name =
(match expr.eexpr with
| TConst const -> self#write_expr_const const
| TLocal var ->
vars#used var.v_name;
self#write ("$" ^ var.v_name)
vars#used (vname var.v_name);
self#write ("$" ^ (vname var.v_name))
| TArray (target, index) -> self#write_expr_array_access target index
| TBinop (OpAssign, { eexpr = TArray (target, index) }, value) when is_array_type target.etype ->
self#write_expr_set_array_item target index value
Expand Down Expand Up @@ -1700,8 +1709,8 @@ class code_writer (ctx:php_generator_context) hx_type_path php_name =
Writes TVar to output buffer
*)
method write_expr_var var expr =
vars#declared var.v_name;
self#write ("$" ^ var.v_name ^ " = ");
vars#declared (vname var.v_name);
self#write ("$" ^ (vname var.v_name) ^ " = ");
match expr with
| None -> self#write "null"
| Some expr -> self#write_expr expr
Expand Down Expand Up @@ -1884,8 +1893,8 @@ class code_writer (ctx:php_generator_context) hx_type_path php_name =
let rec traverse = function
| [] -> ()
| (v,body) :: rest ->
self#write (" catch(" ^ (self#use_t v.v_type) ^ " $" ^ v.v_name ^ ") ");
vars#declared v.v_name;
self#write (" catch(" ^ (self#use_t v.v_type) ^ " $" ^ (vname v.v_name) ^ ") ");
vars#declared (vname v.v_name);
self#write_as_block body;
traverse rest
in
Expand Down Expand Up @@ -2525,7 +2534,7 @@ class code_writer (ctx:php_generator_context) hx_type_path php_name =
if add_parentheses then self#write "(";
self#write_expr collection;
if add_parentheses then self#write ")";
self#write (" as $" ^ key.v_name ^ " => $" ^ value.v_name ^ ") ");
self#write (" as $" ^ (vname key.v_name) ^ " => $" ^ (vname value.v_name) ^ ") ");
self#write_as_block ~unset_locals:true { body with eexpr = TBlock body_exprs };
| _ ->
fail self#pos __LOC__
Expand Down Expand Up @@ -2767,9 +2776,9 @@ class code_writer (ctx:php_generator_context) hx_type_path php_name =
method write_function_arg arg =
match arg with
| ({ v_name = arg_name; v_type = arg_type }, default_value) ->
vars#declared arg_name;
vars#declared (vname arg_name);
if is_ref arg_type then self#write "&";
self#write ("$" ^ arg_name);
self#write ("$" ^ (vname arg_name));
match default_value with
| None -> ()
| Some expr ->
Expand Down
25 changes: 25 additions & 0 deletions tests/unit/src/unit/TestPhp.hx
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,31 @@ class TestPhp extends Test
});
}

@:analyzer(ignore)
function testIssue9924() {
var v = Std.random(10);

var GLOBALS = v;
var _SERVER = v;
var _GET = v;
var _POST = v;
var _FILES = v;
var _COOKIE = v;
var _REQUEST = v;
var _ENV = v;
// var _SESSION = v; //not defined in CLI

utest.Assert.notEquals(GLOBALS, SuperGlobal.GLOBALS);
utest.Assert.notEquals(_SERVER, SuperGlobal._SERVER);
utest.Assert.notEquals(_GET, SuperGlobal._GET);
utest.Assert.notEquals(_POST, SuperGlobal._POST);
utest.Assert.notEquals(_FILES, SuperGlobal._FILES);
utest.Assert.notEquals(_COOKIE, SuperGlobal._COOKIE);
utest.Assert.notEquals(_REQUEST, SuperGlobal._REQUEST);
utest.Assert.notEquals(_ENV, SuperGlobal._ENV);
// utest.Assert.notEquals(_SESSION, SuperGlobal._SESSION);
}

inline static function make():FunctionCallerWrapper {
return new FunctionCaller(function(f) f());
}
Expand Down

0 comments on commit 8c0b13c

Please sign in to comment.