mirror of
https://github.com/php/php-src.git
synced 2024-09-22 10:27:25 +00:00
This commit is contained in:
parent
1efe216585
commit
7aeb4421b7
15
Zend/tests/bug34065.phpt
Executable file
15
Zend/tests/bug34065.phpt
Executable file
@ -0,0 +1,15 @@
|
||||
--TEST--
|
||||
Bug #34065 (throw in foreach causes memory leaks)
|
||||
--FILE--
|
||||
<?php
|
||||
$data = file(__FILE__);
|
||||
try {
|
||||
foreach ($data as $line) {
|
||||
throw new Exception("error");
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
echo "ok\n";
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
ok
|
16
Zend/tests/bug38623.phpt
Executable file
16
Zend/tests/bug38623.phpt
Executable file
@ -0,0 +1,16 @@
|
||||
--TEST--
|
||||
Bug #38623 (leaks in a tricky code with switch() and exceptions)
|
||||
--FILE--
|
||||
<?php
|
||||
try {
|
||||
switch(strtolower("apache")) {
|
||||
case "apache":
|
||||
throw new Exception("test");
|
||||
break;
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
echo "ok\n";
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
ok
|
@ -688,6 +688,7 @@ static inline void do_begin_loop(TSRMLS_D)
|
||||
parent = CG(active_op_array)->current_brk_cont;
|
||||
CG(active_op_array)->current_brk_cont = CG(active_op_array)->last_brk_cont;
|
||||
brk_cont_element = get_next_brk_cont_element(CG(active_op_array));
|
||||
brk_cont_element->start = get_next_op_number(CG(active_op_array));
|
||||
brk_cont_element->parent = parent;
|
||||
}
|
||||
|
||||
|
@ -89,6 +89,7 @@ struct _zend_op {
|
||||
|
||||
|
||||
typedef struct _zend_brk_cont_element {
|
||||
int start;
|
||||
int cont;
|
||||
int brk;
|
||||
int parent;
|
||||
|
@ -3841,7 +3841,8 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
|
||||
{
|
||||
zend_uint op_num = EG(opline_before_exception)-EG(active_op_array)->opcodes;
|
||||
int i;
|
||||
int encapsulating_block=-1;
|
||||
zend_uint catch_op_num;
|
||||
int catched = 0;
|
||||
zval **stack_zval_pp;
|
||||
zval restored_error_reporting;
|
||||
|
||||
@ -3860,7 +3861,8 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
|
||||
}
|
||||
if (op_num >= EG(active_op_array)->try_catch_array[i].try_op
|
||||
&& op_num < EG(active_op_array)->try_catch_array[i].catch_op) {
|
||||
encapsulating_block = i;
|
||||
catched = 1;
|
||||
catch_op_num = EX(op_array)->try_catch_array[i].catch_op;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3876,6 +3878,28 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
|
||||
zend_ptr_stack_2_pop(&EG(arg_types_stack), (void**)&EX(object), (void**)&EX(fbc));
|
||||
}
|
||||
|
||||
for (i=0; i<EX(op_array)->last_brk_cont; i++) {
|
||||
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) {
|
||||
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];
|
||||
|
||||
switch (brk_opline->opcode) {
|
||||
case ZEND_SWITCH_FREE:
|
||||
zend_switch_free(brk_opline, EX(Ts) TSRMLS_CC);
|
||||
break;
|
||||
case ZEND_FREE:
|
||||
zendi_zval_dtor(EX_T(brk_opline->op1.u.var).tmp_var);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* restore previous error_reporting value */
|
||||
if (!EG(error_reporting) && EX(old_error_reporting) != NULL && Z_LVAL_P(EX(old_error_reporting)) != 0) {
|
||||
Z_TYPE(restored_error_reporting) = IS_LONG;
|
||||
@ -3886,10 +3910,10 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
|
||||
}
|
||||
EX(old_error_reporting) = NULL;
|
||||
|
||||
if (encapsulating_block == -1) {
|
||||
if (!catched) {
|
||||
ZEND_VM_RETURN_FROM_EXECUTE_LOOP();
|
||||
} else {
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[EG(active_op_array)->try_catch_array[encapsulating_block].catch_op]);
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
}
|
||||
}
|
||||
|
@ -538,7 +538,8 @@ static int ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
zend_uint op_num = EG(opline_before_exception)-EG(active_op_array)->opcodes;
|
||||
int i;
|
||||
int encapsulating_block=-1;
|
||||
zend_uint catch_op_num;
|
||||
int catched = 0;
|
||||
zval **stack_zval_pp;
|
||||
zval restored_error_reporting;
|
||||
|
||||
@ -557,7 +558,8 @@ static int ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
}
|
||||
if (op_num >= EG(active_op_array)->try_catch_array[i].try_op
|
||||
&& op_num < EG(active_op_array)->try_catch_array[i].catch_op) {
|
||||
encapsulating_block = i;
|
||||
catched = 1;
|
||||
catch_op_num = EX(op_array)->try_catch_array[i].catch_op;
|
||||
}
|
||||
}
|
||||
|
||||
@ -573,6 +575,28 @@ static int ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
zend_ptr_stack_2_pop(&EG(arg_types_stack), (void**)&EX(object), (void**)&EX(fbc));
|
||||
}
|
||||
|
||||
for (i=0; i<EX(op_array)->last_brk_cont; i++) {
|
||||
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) {
|
||||
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];
|
||||
|
||||
switch (brk_opline->opcode) {
|
||||
case ZEND_SWITCH_FREE:
|
||||
zend_switch_free(brk_opline, EX(Ts) TSRMLS_CC);
|
||||
break;
|
||||
case ZEND_FREE:
|
||||
zendi_zval_dtor(EX_T(brk_opline->op1.u.var).tmp_var);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* restore previous error_reporting value */
|
||||
if (!EG(error_reporting) && EX(old_error_reporting) != NULL && Z_LVAL_P(EX(old_error_reporting)) != 0) {
|
||||
Z_TYPE(restored_error_reporting) = IS_LONG;
|
||||
@ -583,10 +607,10 @@ static int ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
}
|
||||
EX(old_error_reporting) = NULL;
|
||||
|
||||
if (encapsulating_block == -1) {
|
||||
if (!catched) {
|
||||
ZEND_VM_RETURN_FROM_EXECUTE_LOOP();
|
||||
} else {
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[EG(active_op_array)->try_catch_array[encapsulating_block].catch_op]);
|
||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
|
||||
ZEND_VM_CONTINUE();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user