From: Bob Weinand Date: Thu, 9 Jul 2015 18:07:40 +0000 (+0200) Subject: Fix too early terminated temporary range with break/cont/goto X-Git-Tag: php-7.1.1RC1~35^2~45 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=cc876c04b420589cb1f62b650d0c0e24975dd4af;p=php Fix too early terminated temporary range with break/cont/goto I have no crashing or leaking reproduce script, only valgrind invalid reads for that one; hence no phpt here --- diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 9cdb5ffd03..4f21769e12 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -3482,7 +3482,7 @@ void zend_compile_return(zend_ast *ast) /* {{{ */ zend_emit_return_type_check(expr_ast ? &expr_node : NULL, CG(active_op_array)->arg_info - 1); } - zend_free_foreach_and_switch_variables(ZEND_FREE_ON_RETURN); + zend_free_foreach_and_switch_variables(ZEND_FREE_ON_JUMP); if (CG(context).in_finally) { opline = zend_emit_op(NULL, ZEND_DISCARD_EXCEPTION, NULL, NULL); @@ -3567,7 +3567,7 @@ void zend_compile_break_continue(zend_ast *ast) /* {{{ */ } if (nest_level > 1) { - generate_free_loop_var(&CG(context).brk_cont_array[array_offset].loop_var); + generate_free_loop_var_ex(&CG(context).brk_cont_array[array_offset].loop_var, ZEND_FREE_ON_JUMP); } array_offset = CG(context).brk_cont_array[array_offset].parent; @@ -3637,7 +3637,7 @@ void zend_resolve_goto_label(zend_op_array *op_array, znode *label_node, zend_op if (pass2_opline) { free_vars++; } else { - generate_free_loop_var(&CG(context).brk_cont_array[current].loop_var); + generate_free_loop_var_ex(&CG(context).brk_cont_array[current].loop_var, ZEND_FREE_ON_JUMP); } } current = CG(context).brk_cont_array[current].parent; diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index b07f70ea78..5560b7e86d 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -882,7 +882,7 @@ ZEND_API void zend_assert_valid_class_name(const zend_string *const_name); #define ZEND_FETCH_ARG_MASK 0x000fffff -#define ZEND_FREE_ON_RETURN (1<<0) +#define ZEND_FREE_ON_JUMP (1<<0) #define ZEND_MEMBER_FUNC_CALL (1<<0) diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index e84edd54b9..6a89a54712 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -994,8 +994,8 @@ static zend_always_inline uint32_t *generate_var_liveliness_info_ex(zend_op_arra && opline->opcode != ZEND_FE_FETCH_RW /* the following opcodes are parts of "return" statement */ && opline->opcode != ZEND_VERIFY_RETURN_TYPE - && (opline->opcode != ZEND_FREE || !(opline->extended_value & ZEND_FREE_ON_RETURN)) - && (opline->opcode != ZEND_FE_FREE || !(opline->extended_value & ZEND_FREE_ON_RETURN)) + && (opline->opcode != ZEND_FREE || !(opline->extended_value & ZEND_FREE_ON_JUMP)) + && (opline->opcode != ZEND_FE_FREE || !(opline->extended_value & ZEND_FREE_ON_JUMP)) ) { op_live_total += liveliness_kill_var(op_array, opline, var, Tstart, opTs); } diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 9b36b804c9..57c8a94867 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -7084,8 +7084,8 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY) if (catch_op_num || finally_op_num) { if (EX(func)->op_array.opcodes[op_num].opcode == ZEND_VERIFY_RETURN_TYPE - || (EX(func)->op_array.opcodes[op_num].opcode == ZEND_FREE && (EX(func)->op_array.opcodes[op_num].extended_value & ZEND_FREE_ON_RETURN)) - || (EX(func)->op_array.opcodes[op_num].opcode == ZEND_FE_FREE && (EX(func)->op_array.opcodes[op_num].extended_value & ZEND_FREE_ON_RETURN)) + || (EX(func)->op_array.opcodes[op_num].opcode == ZEND_FREE && (EX(func)->op_array.opcodes[op_num].extended_value & ZEND_FREE_ON_JUMP)) + || (EX(func)->op_array.opcodes[op_num].opcode == ZEND_FE_FREE && (EX(func)->op_array.opcodes[op_num].extended_value & ZEND_FREE_ON_JUMP)) ) { catch_op_num = finally_op_num = 0; } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 6089b2e3c4..bdfce50cf1 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -1502,8 +1502,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER( if (catch_op_num || finally_op_num) { if (EX(func)->op_array.opcodes[op_num].opcode == ZEND_VERIFY_RETURN_TYPE - || (EX(func)->op_array.opcodes[op_num].opcode == ZEND_FREE && (EX(func)->op_array.opcodes[op_num].extended_value & ZEND_FREE_ON_RETURN)) - || (EX(func)->op_array.opcodes[op_num].opcode == ZEND_FE_FREE && (EX(func)->op_array.opcodes[op_num].extended_value & ZEND_FREE_ON_RETURN)) + || (EX(func)->op_array.opcodes[op_num].opcode == ZEND_FREE && (EX(func)->op_array.opcodes[op_num].extended_value & ZEND_FREE_ON_JUMP)) + || (EX(func)->op_array.opcodes[op_num].opcode == ZEND_FE_FREE && (EX(func)->op_array.opcodes[op_num].extended_value & ZEND_FREE_ON_JUMP)) ) { catch_op_num = finally_op_num = 0; }