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 14:33 UTC Return to Bug #71539 | Download this patchThis patch is obsolete Obsoleted by patches: This patch renders other patches obsolete Obsolete patches: Patch Revisions: 2016-07-06 20:13 UTC | 2016-07-06 19:05 UTC | 2016-07-06 14:33 UTC | 2016-07-06 10:07 UTCDeveloper: dmitry@php.netdiff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 03ab7d1..2137a97 100644 index 03ab7d1..76827b4 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -3026,7 +3026,21 @@ void zend_compile_assign_ref(znode *result, zend_ast *ast) /* {{{ */ @@ -3026,7 +3026,28 @@ 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); - 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_VAR + || target_ast->child[0]->kind != ZEND_AST_ZVAL) + && (source_ast->kind != ZEND_AST_VAR + || source_ast->child[0]->kind != ZEND_AST_ZVAL)) { + if ((target_ast->kind == ZEND_AST_DIM + && source_ast->kind == ZEND_AST_DIM + && target_ast->child[0]->kind != ZEND_AST_DIM) + || (target_ast->kind == ZEND_AST_PROP + && source_ast->kind == ZEND_AST_PROP + && target_ast->child[0]->kind != ZEND_AST_PROP)) { + /* 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_emit_op(&source_node, ZEND_MAKE_REF, &source_node, NULL); + } + zend_op tmp_opline; + + memcpy(&tmp_opline, zend_stack_top(&CG(delayed_oplines_stack)), sizeof(zend_op)); + zend_stack_del_top(&CG(delayed_oplines_stack)); + zend_delayed_compile_var(&source_node, source_ast, BP_VAR_W); + zend_delayed_emit_op(&source_node, ZEND_MAKE_REF, &source_node, NULL); + zend_stack_push(&CG(delayed_oplines_stack), &tmp_opline); + } else { + zend_delayed_compile_var(&source_node, source_ast, BP_VAR_W); + } 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 index f39ce0e..5cae574 100644 index f8082f9..6afc2b7 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -8102,6 +8102,24 @@ ZEND_VM_HANDLER(49, ZEND_CHECK_VAR, CV, UNUSED) @@ -8116,6 +8116,24 @@ ZEND_VM_HANDLER(49, ZEND_CHECK_VAR, CV, UNUSED) ZEND_VM_NEXT_OPCODE(); } +ZEND_VM_HANDLER(51, ZEND_MAKE_REF, VAR, UNUSED) ZEND_VM_TYPE_SPEC_HANDLER(ZEND_ADD, (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_ADD_LONG_NO_OVERFLOW, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(NO_CONST_CONST,COMMUTATIVE)) { USE_OPLINE diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 803414a..83eb35f 100644 index a495b59..a1edc56 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -21821,6 +21821,24 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER( @@ -21857,6 +21857,24 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER( ZEND_VM_RETURN(); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MAKE_REF_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -58465,6 +58483,31 @@ void zend_init_opcodes_handlers(void) @@ -58573,6 +58591,31 @@ void zend_init_opcodes_handlers(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_BOOL_SPEC_CONST_HANDLER, ZEND_BOOL_SPEC_TMPVAR_HANDLER, ZEND_BOOL_SPEC_TMPVAR_HANDLER, @@ -61597,36 +61640,35 @@ void zend_init_opcodes_handlers(void) @@ -61705,36 +61748,35 @@ void zend_init_opcodes_handlers(void) 1433 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 1458 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 1483 | SPEC_RULE_OP1 | SPEC_RULE_QUICK_ARG, - 4571, + 1827 | SPEC_RULE_OP1, 1832 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 1857 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 1882 | SPEC_RULE_OP1 | SPEC_RULE_OP2, @@ -61646,80 +61688,80 @@ void zend_init_opcodes_handlers(void) @@ -61754,80 +61796,80 @@ void zend_init_opcodes_handlers(void) 2232 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 2257 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 2282 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 4571, + 3301 | SPEC_RULE_OP2, 3306 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 3331 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 3356 | SPEC_RULE_OP1 | SPEC_RULE_OP2, @@ -61731,9 +61773,10 @@ void zend_init_opcodes_handlers(void) @@ -61839,9 +61881,10 @@ void zend_init_opcodes_handlers(void) 3506 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 3531 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 3556 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 4571, + 4596 }; zend_opcode_handlers = labels; zend_handlers_count = sizeof(labels) / sizeof(void*); @@ -61840,7 +61883,7 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint @@ -61948,7 +61991,7 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3606 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 3631 | SPEC_RULE_OP1 | SPEC_RULE_OP2; if (op->op1_type > op->op2_type) { zend_swap_operands(op); } @@ -61848,7 +61891,7 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint @@ -61956,7 +61999,7 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3631 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 3656 | SPEC_RULE_OP1 | SPEC_RULE_OP2; if (op->op1_type > op->op2_type) { zend_swap_operands(op); } @@ -61856,7 +61899,7 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint @@ -61964,7 +62007,7 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3656 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 3681 | SPEC_RULE_OP1 | SPEC_RULE_OP2; if (op->op1_type > op->op2_type) { zend_swap_operands(op); } @@ -61867,17 +61910,17 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint @@ -61975,17 +62018,17 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3681 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 3756 | SPEC_RULE_OP1 | SPEC_RULE_OP2; } break; case ZEND_MUL: @@ -61885,7 +61928,7 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint @@ -61993,7 +62036,7 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3756 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 3781 | SPEC_RULE_OP1 | SPEC_RULE_OP2; if (op->op1_type > op->op2_type) { zend_swap_operands(op); } @@ -61893,7 +61936,7 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint @@ -62001,7 +62044,7 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3781 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 3806 | SPEC_RULE_OP1 | SPEC_RULE_OP2; if (op->op1_type > op->op2_type) { zend_swap_operands(op); } @@ -61901,7 +61944,7 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint @@ -62009,7 +62052,7 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3806 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 3831 | SPEC_RULE_OP1 | SPEC_RULE_OP2; if (op->op1_type > op->op2_type) { zend_swap_operands(op); } @@ -61912,7 +61955,7 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint @@ -62020,7 +62063,7 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3831 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 3856 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; if (op->op1_type > op->op2_type) { zend_swap_operands(op); } @@ -61920,7 +61963,7 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint @@ -62028,7 +62071,7 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3906 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 3931 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; if (op->op1_type > op->op2_type) { zend_swap_operands(op); } @@ -61931,7 +61974,7 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint @@ -62039,7 +62082,7 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3981 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 4006 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; if (op->op1_type > op->op2_type) { zend_swap_operands(op); } @@ -61939,7 +61982,7 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint @@ -62047,7 +62090,7 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 4056 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 4081 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; if (op->op1_type > op->op2_type) { zend_swap_operands(op); } @@ -61950,12 +61993,12 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint @@ -62058,12 +62101,12 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 4131 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 4231 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; } break; case ZEND_IS_SMALLER_OR_EQUAL: @@ -61963,70 +62006,70 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint @@ -62071,70 +62114,70 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 4281 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; |
Copyright © 2001-2024 The PHP Group All rights reserved. |
Last updated: Fri Apr 19 08:01:28 2024 UTC |