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)
--FILE--
<?php
$e = new Exception("Bar");
try {
throw new Exception("Foo", 0, $e);
} finally {
throw $e;
$e = new Exception("Foo");
try {
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--
Fatal error: Uncaught exception 'Exception' with message 'Bar' in %sbug70944.php:%d
Stack trace:
#0 {main}
thrown in %sbug70944.php on line %d
--EXPECT--
string(3) "Foo"
string(5) "Dummy"

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");
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)) {
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);
if (Z_TYPE_P(previous) == IS_NULL) {
zend_update_property(default_exception_ce, exception, "previous", sizeof("previous")-1, add_previous TSRMLS_CC);