mirror of
https://github.com/php/php-src.git
synced 2024-09-21 09:57:23 +00:00
Fixed bug #44184 (Double free of loop-variable on exception)
This commit is contained in:
parent
edf53e2073
commit
8c32f99c25
21
Zend/tests/bug44184.phpt
Normal file
21
Zend/tests/bug44184.phpt
Normal file
@ -0,0 +1,21 @@
|
||||
--TEST--
|
||||
Bug #44184 (Double free of loop-variable on exception)
|
||||
--FILE--
|
||||
<?php
|
||||
function foo() {
|
||||
$x = array(1,2,3);
|
||||
foreach ($x as $a) {
|
||||
while (1) {
|
||||
throw new Exception();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
try {
|
||||
foo();
|
||||
} catch (Exception $ex) {
|
||||
echo "ok\n";
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
ok
|
@ -695,8 +695,14 @@ static inline void do_begin_loop(TSRMLS_D)
|
||||
}
|
||||
|
||||
|
||||
static inline void do_end_loop(int cont_addr TSRMLS_DC)
|
||||
static inline void do_end_loop(int cont_addr, int has_loop_var TSRMLS_DC)
|
||||
{
|
||||
if (!has_loop_var) {
|
||||
/* The start fileld is used to free temporary variables in case of exceptions.
|
||||
* We won't try to free something of we don't have loop variable.
|
||||
*/
|
||||
CG(active_op_array)->brk_cont_array[CG(active_op_array)->current_brk_cont].start = -1;
|
||||
}
|
||||
CG(active_op_array)->brk_cont_array[CG(active_op_array)->current_brk_cont].cont = cont_addr;
|
||||
CG(active_op_array)->brk_cont_array[CG(active_op_array)->current_brk_cont].brk = get_next_op_number(CG(active_op_array));
|
||||
CG(active_op_array)->current_brk_cont = CG(active_op_array)->brk_cont_array[CG(active_op_array)->current_brk_cont].parent;
|
||||
@ -731,7 +737,7 @@ void zend_do_while_end(znode *while_token, znode *close_bracket_token TSRMLS_DC)
|
||||
/* update while's conditional jmp */
|
||||
CG(active_op_array)->opcodes[close_bracket_token->u.opline_num].op2.u.opline_num = get_next_op_number(CG(active_op_array));
|
||||
|
||||
do_end_loop(while_token->u.opline_num TSRMLS_CC);
|
||||
do_end_loop(while_token->u.opline_num, 0 TSRMLS_CC);
|
||||
|
||||
DEC_BPC(CG(active_op_array));
|
||||
}
|
||||
@ -775,7 +781,7 @@ void zend_do_for_end(znode *second_semicolon_token TSRMLS_DC)
|
||||
SET_UNUSED(opline->op1);
|
||||
SET_UNUSED(opline->op2);
|
||||
|
||||
do_end_loop(second_semicolon_token->u.opline_num+1 TSRMLS_CC);
|
||||
do_end_loop(second_semicolon_token->u.opline_num+1, 0 TSRMLS_CC);
|
||||
|
||||
DEC_BPC(CG(active_op_array));
|
||||
}
|
||||
@ -2932,7 +2938,7 @@ void zend_do_do_while_end(znode *do_token, znode *expr_open_bracket, znode *expr
|
||||
opline->op2.u.opline_num = do_token->u.opline_num;
|
||||
SET_UNUSED(opline->op2);
|
||||
|
||||
do_end_loop(expr_open_bracket->u.opline_num TSRMLS_CC);
|
||||
do_end_loop(expr_open_bracket->u.opline_num, 0 TSRMLS_CC);
|
||||
|
||||
DEC_BPC(CG(active_op_array));
|
||||
}
|
||||
@ -4326,7 +4332,7 @@ void zend_do_foreach_end(znode *foreach_token, znode *as_token TSRMLS_DC)
|
||||
CG(active_op_array)->opcodes[foreach_token->u.opline_num].op2.u.opline_num = get_next_op_number(CG(active_op_array)); /* FE_RESET */
|
||||
CG(active_op_array)->opcodes[as_token->u.opline_num].op2.u.opline_num = get_next_op_number(CG(active_op_array)); /* FE_FETCH */
|
||||
|
||||
do_end_loop(as_token->u.opline_num TSRMLS_CC);
|
||||
do_end_loop(as_token->u.opline_num, 1 TSRMLS_CC);
|
||||
|
||||
zend_stack_top(&CG(foreach_copy_stack), (void **) &container_ptr);
|
||||
generate_free_foreach_copy(container_ptr TSRMLS_CC);
|
||||
|
@ -4052,11 +4052,12 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
|
||||
}
|
||||
|
||||
for (i=0; i<EX(op_array)->last_brk_cont; i++) {
|
||||
if (EX(op_array)->brk_cont_array[i].start > op_num) {
|
||||
if (EX(op_array)->brk_cont_array[i].start < 0) {
|
||||
continue;
|
||||
} else if (EX(op_array)->brk_cont_array[i].start > op_num) {
|
||||
/* further blocks will not be relevant... */
|
||||
break;
|
||||
}
|
||||
if (op_num < EX(op_array)->brk_cont_array[i].brk) {
|
||||
} else if (op_num < EX(op_array)->brk_cont_array[i].brk) {
|
||||
if (!catched ||
|
||||
catch_op_num >= EX(op_array)->brk_cont_array[i].brk) {
|
||||
zend_op *brk_opline = &EX(op_array)->opcodes[EX(op_array)->brk_cont_array[i].brk];
|
||||
|
@ -556,11 +556,12 @@ static int ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
}
|
||||
|
||||
for (i=0; i<EX(op_array)->last_brk_cont; i++) {
|
||||
if (EX(op_array)->brk_cont_array[i].start > op_num) {
|
||||
if (EX(op_array)->brk_cont_array[i].start < 0) {
|
||||
continue;
|
||||
} else if (EX(op_array)->brk_cont_array[i].start > op_num) {
|
||||
/* further blocks will not be relevant... */
|
||||
break;
|
||||
}
|
||||
if (op_num < EX(op_array)->brk_cont_array[i].brk) {
|
||||
} else if (op_num < EX(op_array)->brk_cont_array[i].brk) {
|
||||
if (!catched ||
|
||||
catch_op_num >= EX(op_array)->brk_cont_array[i].brk) {
|
||||
zend_op *brk_opline = &EX(op_array)->opcodes[EX(op_array)->brk_cont_array[i].brk];
|
||||
|
Loading…
Reference in New Issue
Block a user