From: Dmitry Stogov Date: Thu, 12 Oct 2017 13:23:45 +0000 (+0300) Subject: PHP must not create circular arrays when element is assigned by value. X-Git-Tag: php-7.3.0alpha1~1282 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=edc7c8ccfa0eb7c6064575e2155f30797adf6684;p=php PHP must not create circular arrays when element is assigned by value. --- diff --git a/Zend/tests/gc_032.phpt b/Zend/tests/gc_032.phpt index b11a6655f1..d0d36b2b35 100644 --- a/Zend/tests/gc_032.phpt +++ b/Zend/tests/gc_032.phpt @@ -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){ + } } } } diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 8d353b8c0a..5e85a26957 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -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); }