From 8c0b13c39527b877986dcef599abb32b0ac845f2 Mon Sep 17 00:00:00 2001 From: Aleksandr Kuzmenko Date: Tue, 20 Oct 2020 19:09:09 +0300 Subject: [PATCH] [php] rename local vars with the same names as super global vars (fixes #9924) --- extra/CHANGES.txt | 1 + src/generators/genphp7.ml | 27 ++++++++++++++++++--------- tests/unit/src/unit/TestPhp.hx | 25 +++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 9 deletions(-) diff --git a/extra/CHANGES.txt b/extra/CHANGES.txt index 11f37ec7c6c..3a18f3dbe38 100644 --- a/extra/CHANGES.txt +++ b/extra/CHANGES.txt @@ -4,6 +4,7 @@ jvm : fixed equality checks for `Null` and `Null` (#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: diff --git a/src/generators/genphp7.ml b/src/generators/genphp7.ml index fb7237e376a..fa36a42e132 100644 --- a/src/generators/genphp7.ml +++ b/src/generators/genphp7.ml @@ -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. *) @@ -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 @@ -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 @@ -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 @@ -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__ @@ -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 -> diff --git a/tests/unit/src/unit/TestPhp.hx b/tests/unit/src/unit/TestPhp.hx index 3eafa9a512a..6fb43ed5e31 100644 --- a/tests/unit/src/unit/TestPhp.hx +++ b/tests/unit/src/unit/TestPhp.hx @@ -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()); }