php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Return to Bug #71539
Patch bug71539.diff revision 2016-07-06 20:13 UTC by dmitry@php.net
revision 2016-07-06 19:05 UTC by dmitry@php.net
revision 2016-07-06 14:33 UTC by dmitry@php.net
revision 2016-07-06 10:07 UTC by dmitry@php.net

Patch bug71539.diff for Scripting Engine problem Bug #71539

Patch version 2016-07-06 20:13 UTC

Return to Bug #71539 | Download this patch
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 UTC

Developer: dmitry@php.net

Line 1 (now 1), was 41 lines, now 36 lines

  diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
 index 03ab7d1..a1ec348 100644
 index 03ab7d1..2137a97 100644
  --- a/Zend/zend_compile.c
  +++ b/Zend/zend_compile.c
 @@ -3026,7 +3026,26 @@ 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);
  -	zend_delayed_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)) {
 +	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)) {
  +		/* 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_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_emit_op(&source_node, ZEND_MAKE_REF, &source_node, NULL);
  +	}
 +
   	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 f8082f9..6afc2b7 100644
 index f39ce0e..5cae574 100644
  --- a/Zend/zend_vm_def.h
  +++ b/Zend/zend_vm_def.h
 @@ -8116,6 +8116,24 @@ ZEND_VM_HANDLER(49, ZEND_CHECK_VAR, CV, UNUSED)
 @@ -8102,6 +8102,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 a495b59..a1edc56 100644
 index 803414a..83eb35f 100644
  --- a/Zend/zend_vm_execute.h
  +++ b/Zend/zend_vm_execute.h
 @@ -21857,6 +21857,24 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER(
 @@ -21821,6 +21821,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
 @@ -58573,6 +58591,31 @@ void zend_init_opcodes_handlers(void)
 @@ -58465,6 +58483,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,
 @@ -61705,36 +61748,35 @@ void zend_init_opcodes_handlers(void)
 @@ -61597,36 +61640,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,
 @@ -61754,80 +61796,80 @@ void zend_init_opcodes_handlers(void)
 @@ -61646,80 +61688,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,
 @@ -61839,9 +61881,10 @@ void zend_init_opcodes_handlers(void)
 @@ -61731,9 +61773,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*);
 @@ -61948,7 +61991,7 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint
 @@ -61840,7 +61883,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);
   				}
 @@ -61956,7 +61999,7 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint
 @@ -61848,7 +61891,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);
   				}
 @@ -61964,7 +62007,7 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint
 @@ -61856,7 +61899,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);
   				}
 @@ -61975,17 +62018,17 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint
 @@ -61867,17 +61910,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:
 @@ -61993,7 +62036,7 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint
 @@ -61885,7 +61928,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);
   				}
 @@ -62001,7 +62044,7 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint
 @@ -61893,7 +61936,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);
   				}
 @@ -62009,7 +62052,7 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint
 @@ -61901,7 +61944,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);
   				}
 @@ -62020,7 +62063,7 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint
 @@ -61912,7 +61955,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);
   				}
 @@ -62028,7 +62071,7 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint
 @@ -61920,7 +61963,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);
   				}
 @@ -62039,7 +62082,7 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint
 @@ -61931,7 +61974,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);
   				}
 @@ -62047,7 +62090,7 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint
 @@ -61939,7 +61982,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);
   				}
 @@ -62058,12 +62101,12 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint
 @@ -61950,12 +61993,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:
 @@ -62071,70 +62114,70 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint
 @@ -61963,70 +62006,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;
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 03:01:20 2019 UTC