]> granicus.if.org Git - php/commitdiff
PHP must not create circular arrays when element is assigned by value.
authorDmitry Stogov <dmitry@zend.com>
Thu, 12 Oct 2017 13:23:45 +0000 (16:23 +0300)
committerDmitry Stogov <dmitry@zend.com>
Thu, 12 Oct 2017 13:23:45 +0000 (16:23 +0300)
Zend/tests/gc_032.phpt
Zend/zend_compile.c

index b11a6655f166d071dcbeb05aa218d55fb85af85f..d0d36b2b351f56a46269948cc8fcdda731047c4c 100644 (file)
@@ -14,20 +14,19 @@ $a[0][0] = $a;
 debug_zval_dump($a);
 ?>
 --EXPECTF--
-array(1) refcount(%d){
+array(1) refcount(2){
   [0]=>
-  array(1) refcount(%d){
-    [0]=>
-    *RECURSION*
+  array(0) refcount(1){
   }
 }
-array(1) refcount(%d){
+array(1) refcount(2){
   [0]=>
-  array(1) refcount(%d){
+  array(1) refcount(1){
     [0]=>
-    array(1) refcount(%d){
+    array(1) refcount(1){
       [0]=>
-      *RECURSION*
+      array(0) refcount(1){
+      }
     }
   }
 }
index 8d353b8c0a85af828f814672e4553b8e7e084a41..5e85a2695743181be5d496e009b34de7a49b7173 100644 (file)
@@ -3000,7 +3000,13 @@ void zend_compile_assign(znode *result, zend_ast *ast) /* {{{ */
                        if (zend_is_assign_to_self(var_ast, expr_ast)
                         && !is_this_fetch(expr_ast)) {
                                /* $a[0] = $a should evaluate the right $a first */
-                               zend_compile_simple_var_no_cv(&expr_node, expr_ast, BP_VAR_R, 0);
+                               znode cv_node;
+
+                               if (zend_try_compile_cv(&cv_node, expr_ast) == FAILURE) {
+                                       zend_compile_simple_var_no_cv(&expr_node, expr_ast, BP_VAR_R, 0);
+                               } else {
+                                       zend_emit_op(&expr_node, ZEND_QM_ASSIGN, &cv_node, NULL);
+                               }
                        } else {
                                zend_compile_expr(&expr_node, expr_ast);
                        }
@@ -3023,7 +3029,13 @@ void zend_compile_assign(znode *result, zend_ast *ast) /* {{{ */
                case ZEND_AST_ARRAY:
                        if (zend_list_has_assign_to_self(var_ast, expr_ast)) {
                                /* list($a, $b) = $a should evaluate the right $a first */
-                               zend_compile_simple_var_no_cv(&expr_node, expr_ast, BP_VAR_R, 0);
+                               znode cv_node;
+
+                               if (zend_try_compile_cv(&cv_node, expr_ast) == FAILURE) {
+                                       zend_compile_simple_var_no_cv(&expr_node, expr_ast, BP_VAR_R, 0);
+                               } else {
+                                       zend_emit_op(&expr_node, ZEND_QM_ASSIGN, &cv_node, NULL);
+                               }
                        } else {
                                zend_compile_expr(&expr_node, expr_ast);
                        }