+++ /dev/null
---TEST--
-Bug #72213 (Finally leaks on nested exceptions)
---FILE--
-<?php
-function test() {
- try {
- throw new Exception('a');
- } finally {
- try {
- throw new Exception('b');
- } finally {
- }
- }
-}
-
-try {
- test();
-} catch (Exception $e) {
- var_dump($e->getMessage());
- var_dump($e->getPrevious()->getMessage());
-}
-?>
---EXPECT--
-string(1) "b"
-string(1) "a"
{
uint32_t op_num = EG(opline_before_exception) - EX(func)->op_array.opcodes;
int i;
- uint32_t catch_op_num = 0, finally_op_num = 0, finally_op_end = 0, prev_finally_op_end = 0;
+ uint32_t catch_op_num = 0, finally_op_num = 0, finally_op_end = 0;
int in_finally = 0;
{
if (op_num >= EX(func)->op_array.try_catch_array[i].finally_op &&
op_num < EX(func)->op_array.try_catch_array[i].finally_end) {
finally_op_end = EX(func)->op_array.try_catch_array[i].finally_end;
- prev_finally_op_end = finally_op_end;
in_finally = 1;
}
}
zval *fast_call = EX_VAR(EX(func)->op_array.opcodes[finally_op_end].op1.var);
cleanup_live_vars(execute_data, op_num, finally_op_num);
- if (prev_finally_op_end) {
- zval *prev_fast_call = EX_VAR(EX(func)->op_array.opcodes[prev_finally_op_end].op1.var);
-
- if (Z_OBJ_P(prev_fast_call)) {
- zend_exception_set_previous(EG(exception), Z_OBJ_P(prev_fast_call));
- Z_OBJ_P(prev_fast_call) = NULL;
- }
+ if (in_finally && Z_OBJ_P(fast_call)) {
+ zend_exception_set_previous(EG(exception), Z_OBJ_P(fast_call));
}
Z_OBJ_P(fast_call) = EG(exception);
EG(exception) = NULL;
{
uint32_t op_num = EG(opline_before_exception) - EX(func)->op_array.opcodes;
int i;
- uint32_t catch_op_num = 0, finally_op_num = 0, finally_op_end = 0, prev_finally_op_end = 0;
+ uint32_t catch_op_num = 0, finally_op_num = 0, finally_op_end = 0;
int in_finally = 0;
{
if (op_num >= EX(func)->op_array.try_catch_array[i].finally_op &&
op_num < EX(func)->op_array.try_catch_array[i].finally_end) {
finally_op_end = EX(func)->op_array.try_catch_array[i].finally_end;
- prev_finally_op_end = finally_op_end;
in_finally = 1;
}
}
zval *fast_call = EX_VAR(EX(func)->op_array.opcodes[finally_op_end].op1.var);
cleanup_live_vars(execute_data, op_num, finally_op_num);
- if (prev_finally_op_end) {
- zval *prev_fast_call = EX_VAR(EX(func)->op_array.opcodes[prev_finally_op_end].op1.var);
-
- if (Z_OBJ_P(prev_fast_call)) {
- zend_exception_set_previous(EG(exception), Z_OBJ_P(prev_fast_call));
- Z_OBJ_P(prev_fast_call) = NULL;
- }
+ if (in_finally && Z_OBJ_P(fast_call)) {
+ zend_exception_set_previous(EG(exception), Z_OBJ_P(fast_call));
}
Z_OBJ_P(fast_call) = EG(exception);
EG(exception) = NULL;