Improved fix for bug #70944

This commit is contained in:
Xinchen Hui 2015-11-21 00:27:56 -08:00
parent a1c887964e
commit 7b195c9875
2 changed files with 30 additions and 16 deletions

View file

@ -2,15 +2,28 @@
Bug #70944 (try{ } finally{} can create infinite chains of exceptions) Bug #70944 (try{ } finally{} can create infinite chains of exceptions)
--FILE-- --FILE--
<?php <?php
$e = new Exception("Bar");
try { try {
throw new Exception("Foo", 0, $e); $e = new Exception("Foo");
} finally { try {
throw $e; throw new Exception("Bar", 0, $e);
} finally {
throw $e;
}
} catch (Exception $e) {
var_dump($e->getMessage());
}
try {
$e = new Exception("Foo");
try {
throw new Exception("Bar", 0, $e);
} finally {
throw new Exception("Dummy", 0, $e);
}
} catch (Exception $e) {
var_dump($e->getMessage());
} }
?> ?>
--EXPECTF-- --EXPECT--
Fatal error: Uncaught exception 'Exception' with message 'Bar' in %sbug70944.php:%d string(3) "Foo"
Stack trace: string(5) "Dummy"
#0 {main}
thrown in %sbug70944.php on line %d

View file

@ -45,14 +45,15 @@ void zend_exception_set_previous(zval *exception, zval *add_previous TSRMLS_DC)
zend_error(E_ERROR, "Cannot set non exception as previous exception"); zend_error(E_ERROR, "Cannot set non exception as previous exception");
return; return;
} }
ancestor = zend_read_property(default_exception_ce, add_previous, "previous", sizeof("previous")-1, 1 TSRMLS_CC);
while (Z_TYPE_P(ancestor) == IS_OBJECT) {
if (Z_OBJ_HANDLE_P(ancestor) == Z_OBJ_HANDLE_P(exception)) {
return;
}
ancestor = zend_read_property(default_exception_ce, ancestor, "previous", sizeof("previous")-1, 1 TSRMLS_CC);
}
while (exception && exception != add_previous && Z_OBJ_HANDLE_P(exception) != Z_OBJ_HANDLE_P(add_previous)) { while (exception && exception != add_previous && Z_OBJ_HANDLE_P(exception) != Z_OBJ_HANDLE_P(add_previous)) {
ancestor = zend_read_property(default_exception_ce, add_previous, "previous", sizeof("previous")-1, 1 TSRMLS_CC);
while (Z_TYPE_P(ancestor) == IS_OBJECT) {
if (Z_OBJ_HANDLE_P(ancestor) == Z_OBJ_HANDLE_P(exception)) {
zval_ptr_dtor(&add_previous);
return;
}
ancestor = zend_read_property(default_exception_ce, ancestor, "previous", sizeof("previous")-1, 1 TSRMLS_CC);
}
previous = zend_read_property(default_exception_ce, exception, "previous", sizeof("previous")-1, 1 TSRMLS_CC); previous = zend_read_property(default_exception_ce, exception, "previous", sizeof("previous")-1, 1 TSRMLS_CC);
if (Z_TYPE_P(previous) == IS_NULL) { if (Z_TYPE_P(previous) == IS_NULL) {
zend_update_property(default_exception_ce, exception, "previous", sizeof("previous")-1, add_previous TSRMLS_CC); zend_update_property(default_exception_ce, exception, "previous", sizeof("previous")-1, add_previous TSRMLS_CC);