]> 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)
Zend/tests/bug52361.phpt [new file with mode: 0644]
Zend/zend_objects.c

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 6a87284cede1e19c1f3452649fb76d5f0a1067d3..cfd9a4ef82ff5e7b3c123b060041f306d65e8b2d 100644 (file)
@@ -117,15 +117,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;
                        }