Skip to content

Instantly share code, notes, and snippets.

@reeze
Last active November 21, 2015 06:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save reeze/1f27b4563a74c6d3c3ca to your computer and use it in GitHub Desktop.
Save reeze/1f27b4563a74c6d3c3ca to your computer and use it in GitHub Desktop.
0001-Improved-fix-for-bug-70944.patch
From 3899310384cd2416156dd54d9a6fa2889ba16698 Mon Sep 17 00:00:00 2001
From: Reeze Xia <reeze@php.net>
Date: Sat, 21 Nov 2015 13:46:07 +0800
Subject: [PATCH] Improved fix for bug #70944
---
Zend/tests/bug70944-2.phpt | 20 ++++++++++++++++++++
Zend/zend_exceptions.c | 18 +++++++++++++-----
2 files changed, 33 insertions(+), 5 deletions(-)
create mode 100644 Zend/tests/bug70944-2.phpt
diff --git a/Zend/tests/bug70944-2.phpt b/Zend/tests/bug70944-2.phpt
new file mode 100644
index 0000000..998eb98
--- /dev/null
+++ b/Zend/tests/bug70944-2.phpt
@@ -0,0 +1,20 @@
+--TEST--
+Bug #70944 (try{ } finally{} can create infinite chains of exceptions) 2
+--FILE--
+<?php
+$e = new Exception("Bar");
+try {
+ throw new Exception("Foo", 0, $e);
+} finally {
+ throw new Exception("Foo2", 0, $e);
+}
+?>
+--EXPECTF--
+Fatal error: Uncaught exception 'Exception' with message 'Bar' in %sbug70944-2.php:%d
+Stack trace:
+#0 {main}
+
+Next exception 'Exception' with message 'Foo2' in %sbug70944-2.php:%d
+Stack trace:
+#0 {main}
+ thrown in %sbug70944-2.php on line %d
diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c
index d1aa6fe..7457942 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, *ancestor;
+ zval *previous, *ancestor, *a, *e;
if (exception == add_previous || !add_previous || !exception) {
return;
@@ -45,13 +45,21 @@ void zend_exception_set_previous(zval *exception, zval *add_previous TSRMLS_DC)
zend_error(E_ERROR, "Cannot set non exception as previous exception");
return;
}
+
+ /* avoid possible cycle */
+ e = exception;
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;
+ while (Z_TYPE_P(e) == IS_OBJECT) {
+ a = ancestor;
+ while (Z_TYPE_P(a) == IS_OBJECT) {
+ if (Z_OBJ_HANDLE_P(a) == Z_OBJ_HANDLE_P(e)) {
+ return;
+ }
+ a = zend_read_property(default_exception_ce, a, "previous", sizeof("previous")-1, 1 TSRMLS_CC);
}
- ancestor = zend_read_property(default_exception_ce, ancestor, "previous", sizeof("previous")-1, 1 TSRMLS_CC);
+ e = zend_read_property(default_exception_ce, e, "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) {
--
2.4.9 (Apple Git-60)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment