php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login | |
Patch bug71539.diff for Scripting Engine problem Bug #71539Patch version 2016-07-06 20:13 UTC Return to Bug #71539 | Download this patchThis patch renders other patches obsolete Obsolete patches:
Developer: dmitry@php.netLine 1 (now 1), was 38 lines, now 28 lines diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 03ab7d1..5fd6bee 100644 index 03ab7d1..2137a97 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -3017,7 +3017,7 @@ void zend_compile_assign_ref(znode *result, zend_ast *ast) /* {{{ */ znode target_node, source_node; zend_op *opline; - uint32_t offset; + uint32_t offset, offset2; if (is_this_fetch(target_ast)) { zend_error_noreturn(E_COMPILE_ERROR, "Cannot re-assign $this"); @@ -3026,7 +3026,23 @@ void zend_compile_assign_ref(znode *result, zend_ast *ast) /* {{{ */ @@ -3026,7 +3026,21 @@ void zend_compile_assign_ref(znode *result, zend_ast *ast) /* {{{ */ offset = zend_delayed_compile_begin(); zend_delayed_compile_var(&target_node, target_ast, BP_VAR_W); + offset2 = zend_delayed_compile_begin(); zend_delayed_compile_var(&source_node, source_ast, BP_VAR_W); - zend_delayed_compile_var(&source_node, source_ast, BP_VAR_W); + zend_compile_var(&source_node, source_ast, BP_VAR_W); + + if ((target_ast->kind == ZEND_AST_DIM + && source_ast->kind == ZEND_AST_DIM) + || (target_ast->kind == ZEND_AST_PROP + && source_ast->kind == ZEND_AST_PROP)) { + if ((target_ast->kind != ZEND_AST_VAR + || target_ast->child[0]->kind != ZEND_AST_ZVAL) + && (source_ast->kind != ZEND_AST_VAR + || source_ast->child[0]->kind != ZEND_AST_ZVAL)) { + /* Both LHS and RHS expressions may modify the same data structure, + * and the modification during RHS evaluation may dangle the pointer + * to the result of the LHS evaluation. + * Use MAKE_REF instruction to replace direct pointer with REFERENCE. + * See: Bug #71539 + */ + zend_delayed_emit_op(&source_node, ZEND_MAKE_REF, &source_node, NULL); + zend_emit_op(&source_node, ZEND_MAKE_REF, &source_node, NULL); + } + + zend_delayed_compile_end(offset2); zend_delayed_compile_end(offset); if (source_node.op_type != IS_VAR && zend_is_call(source_ast)) { diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h |
Copyright © 2001-2024 The PHP Group All rights reserved. |
Last updated: Fri Apr 19 02:01:29 2024 UTC |