]> granicus.if.org Git - php/commitdiff
Bug #52361 (Throwing an exception in a destructor causes invalid catching)
authorDmitry Stogov <dmitry@php.net>
Mon, 16 Aug 2010 09:20:46 +0000 (09:20 +0000)
committerDmitry Stogov <dmitry@php.net>
Mon, 16 Aug 2010 09:20:46 +0000 (09:20 +0000)
NEWS
Zend/tests/bug52361.phpt [new file with mode: 0644]
Zend/zend_objects.c

diff --git a/NEWS b/NEWS
index 36a0b2b9354d6da8021d99a641e7820880b87745..2b76fc6c7343857aa917ea8e014c04a0a66cb255 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -24,6 +24,8 @@
   (Andrey)
 - Fixed bug #52413 (MySQLi/libmysql build failure on OS X, FreeBSD). (Andrey)
 - Fixed bug #52390 (mysqli_report() should be per-request setting). (Kalle)
+- Fixed bug #52361 (Throwing an exception in a destructor causes invalid
+  catching). (Dmitry)
 - Fixed bug #52302 (mysqli_fetch_all does not work with MYSQLI_USE_RESULT).
   (Andrey)
 - Fixed bug #51610 (Using oci_connect causes PHP to take a long time to
diff --git a/Zend/tests/bug52361.phpt b/Zend/tests/bug52361.phpt
new file mode 100644 (file)
index 0000000..3c2dffa
--- /dev/null
@@ -0,0 +1,35 @@
+--TEST--
+Bug #52361 (Throwing an exception in a destructor causes invalid catching)
+--FILE--
+<?php
+class aaa {
+       public function __destruct() {
+               try {
+                       throw new Exception(__CLASS__);
+               } catch(Exception $ex) {
+                       echo "1. $ex\n";
+               }
+       }
+}
+function bbb() {
+       $a = new aaa();
+       throw new Exception(__FUNCTION__);
+}
+try {
+       bbb();
+       echo "must be skipped !!!";
+} catch(Exception $ex) {
+       echo "2. $ex\n";
+}
+?>
+--EXPECTF--
+1. exception 'Exception' with message 'aaa' in %sbug52361.php:5
+Stack trace:
+#0 %sbug52361.php(16): aaa->__destruct()
+#1 %sbug52361.php(16): bbb()
+#2 {main}
+2. exception 'Exception' with message 'bbb' in %sbug52361.php:13
+Stack trace:
+#0 %sbug52361.php(16): bbb()
+#1 {main}
+
index ed9dc7c76c73583cb1c72c7f91d000139e33d722..9574f1d2cd71ae1b2f77ce9ecc1126177fa8a88e 100644 (file)
@@ -106,15 +106,13 @@ ZEND_API void zend_objects_destroy_object(zend_object *object, zend_object_handl
                                zend_error(E_ERROR, "Attempt to destruct pending exception");
                        } else {
                                old_exception = EG(exception);
-                               Z_ADDREF_P(old_exception);
+                               EG(exception) = NULL;
                        }
                }
-               zend_exception_save(TSRMLS_C);
                zend_call_method_with_0_params(&obj, object->ce, &destructor, ZEND_DESTRUCTOR_FUNC_NAME, NULL);
-               zend_exception_restore(TSRMLS_C);
                if (old_exception) {
                        if (EG(exception)) {
-                               zval_ptr_dtor(&old_exception);                          
+                               zend_exception_set_previous(EG(exception), old_exception TSRMLS_CC);
                        } else {
                                EG(exception) = old_exception;
                        }