summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS4
-rw-r--r--Zend/tests/bug70944.phpt16
-rw-r--r--Zend/zend_exceptions.c9
3 files changed, 28 insertions, 1 deletions
diff --git a/NEWS b/NEWS
index 72cd4f9ed0..189d9e0301 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,10 @@ PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
?? ??? 2015, PHP 5.6.17
+- Core:
+ . Fixed bug #70944 (try{ } finally{} can create infinite chains of
+ exceptions). (Laruence)
+
- Mysqlnd:
. Fixed bug #68077 (LOAD DATA LOCAL INFILE / open_basedir restriction).
(Laruence)
diff --git a/Zend/tests/bug70944.phpt b/Zend/tests/bug70944.phpt
new file mode 100644
index 0000000000..d189d9eab4
--- /dev/null
+++ b/Zend/tests/bug70944.phpt
@@ -0,0 +1,16 @@
+--TEST--
+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;
+}
+?>
+--EXPECTF--
+Fatal error: Uncaught exception 'Exception' with message 'Bar' in %sbug70944.php:%d
+Stack trace:
+#0 {main}
+ thrown in %sbug70944.php on line %d
diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c
index 40248f7f5e..d1aa6fe9f1 100644
--- a/Zend/zend_exceptions.c
+++ b/Zend/zend_exceptions.c
@@ -36,7 +36,7 @@ ZEND_API void (*zend_throw_exception_hook)(zval *ex TSRMLS_DC);
void zend_exception_set_previous(zval *exception, zval *add_previous TSRMLS_DC)
{
- zval *previous;
+ zval *previous, *ancestor;
if (exception == add_previous || !add_previous || !exception) {
return;
@@ -45,6 +45,13 @@ 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)) {
previous = zend_read_property(default_exception_ce, exception, "previous", sizeof("previous")-1, 1 TSRMLS_CC);
if (Z_TYPE_P(previous) == IS_NULL) {