diff --git a/Library/Backends/ZendEngine2/Backend.php b/Library/Backends/ZendEngine2/Backend.php index 9427aef30b..d1f6ac16ac 100644 --- a/Library/Backends/ZendEngine2/Backend.php +++ b/Library/Backends/ZendEngine2/Backend.php @@ -22,6 +22,7 @@ use Zephir\Fcall\FcallManagerInterface; use Zephir\GlobalConstant; use Zephir\Variable; +use Zephir\Variable\Globals; /** * Zephir\Backends\ZendEngine2\Backend. @@ -1186,7 +1187,12 @@ public function setSymbolIfSeparated(Variable $variableTempSeparated, Variable $ public function copyOnWrite(Variable $target, $var, CompilationContext $context) { - $context->codePrinter->output('ZEPHIR_CPY_WRT('.$this->getVariableCode($target).', '.$this->resolveValue($var, $context).');'); + $globalsManager = new Globals(); + if ($globalsManager->isSuperGlobal($target->getName())) { + $context->codePrinter->output('ZEPHIR_HASH_COPY('.$this->getVariableCode($target).', '.$this->resolveValue($var, $context).');'); + } else { + $context->codePrinter->output('ZEPHIR_CPY_WRT('.$this->getVariableCode($target).', '.$this->resolveValue($var, $context).');'); + } } public function forStatement(Variable $exprVariable, $keyVariable, $variable, $duplicateKey, $duplicateHash, $statement, $statementBlock, CompilationContext $compilationContext) diff --git a/kernels/ZendEngine3/memory.h b/kernels/ZendEngine3/memory.h index 74142f0dea..316399fef6 100644 --- a/kernels/ZendEngine3/memory.h +++ b/kernels/ZendEngine3/memory.h @@ -151,6 +151,11 @@ int zephir_set_symbol_str(char *key_name, unsigned int key_length, zval *value); ZEPHIR_OBS_VAR_ONCE(z); \ ZVAL_COPY(z, v); +#define ZEPHIR_HASH_COPY(z, v) \ + if (Z_TYPE_P(z) == IS_ARRAY && Z_TYPE_P(v) == IS_ARRAY) { \ + zend_hash_copy(Z_ARRVAL_P(z), Z_ARRVAL_P(v), (copy_ctor_func_t) zval_add_ref); \ + } + #define ZEPHIR_OBS_NVAR(z) \ if (Z_TYPE_P(z) != IS_UNDEF) { \ if (Z_REFCOUNTED_P(z) && Z_REFCOUNT_P(z) > 1) { \ diff --git a/test/assign.zep b/test/assign.zep index ff6a8383f2..105068f803 100644 --- a/test/assign.zep +++ b/test/assign.zep @@ -923,4 +923,20 @@ class Assign let _GET["stestint2"] = 2; let _GET[v] = "testval"; } + + /** + * @link https://github.com/phalcon/zephir/issues/1917 + */ + public function testAssignSuperGlobalsSERVER() + { + let _SERVER = array_merge(_SERVER, ["g1": "aaa", "g2": "bbb"]); + } + + /** + * @link https://github.com/phalcon/zephir/issues/1917 + */ + public function testAssignSuperGlobalsGET() + { + let _GET = array_merge(_GET, ["g1": "aaa", "g2": "bbb"]); + } } diff --git a/unit-tests/Extension/AssignTest.php b/unit-tests/Extension/AssignTest.php index 6326c0fe29..348bc82624 100644 --- a/unit-tests/Extension/AssignTest.php +++ b/unit-tests/Extension/AssignTest.php @@ -159,4 +159,24 @@ public function testGlobalVarAssign() $this->assertSame($_GET['stestint2'], 2); $this->assertSame($_GET['stest2'], 'testval'); } + + public function testGlobalVarAssignSERVER() + { + $serverCount = count($_SERVER); + + $t = new Assign(); + $t->testAssignSuperGlobalsSERVER(); + + $this->assertSame($serverCount + 2, count($_SERVER)); + } + + public function testGlobalVarAssignGET() + { + $getCount = count($_GET); + + $t = new Assign(); + $t->testAssignSuperGlobalsGET(); + + $this->assertSame($getCount + 2, count($_GET)); + } }