dmitry                                   Mon, 16 Aug 2010 09:20:46 +0000

Revision: http://svn.php.net/viewvc?view=revision&revision=302323

Log:
Bug #52361 (Throwing an exception in a destructor causes invalid catching)

Bug: http://bugs.php.net/52361 (Assigned) Throwing an exception in a destructor 
causes invalid catching
      
Changed paths:
    U   php/php-src/branches/PHP_5_3/NEWS
    A   php/php-src/branches/PHP_5_3/Zend/tests/bug52361.phpt
    U   php/php-src/branches/PHP_5_3/Zend/zend_objects.c
    A   php/php-src/trunk/Zend/tests/bug52361.phpt
    U   php/php-src/trunk/Zend/zend_objects.c

Modified: php/php-src/branches/PHP_5_3/NEWS
===================================================================
--- php/php-src/branches/PHP_5_3/NEWS   2010-08-16 09:13:21 UTC (rev 302322)
+++ php/php-src/branches/PHP_5_3/NEWS   2010-08-16 09:20:46 UTC (rev 302323)
@@ -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

Added: php/php-src/branches/PHP_5_3/Zend/tests/bug52361.phpt
===================================================================
--- php/php-src/branches/PHP_5_3/Zend/tests/bug52361.phpt                       
        (rev 0)
+++ php/php-src/branches/PHP_5_3/Zend/tests/bug52361.phpt       2010-08-16 
09:20:46 UTC (rev 302323)
@@ -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}
+

Modified: php/php-src/branches/PHP_5_3/Zend/zend_objects.c
===================================================================
--- php/php-src/branches/PHP_5_3/Zend/zend_objects.c    2010-08-16 09:13:21 UTC 
(rev 302322)
+++ php/php-src/branches/PHP_5_3/Zend/zend_objects.c    2010-08-16 09:20:46 UTC 
(rev 302323)
@@ -106,15 +106,13 @@
                                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;
                        }

Added: php/php-src/trunk/Zend/tests/bug52361.phpt
===================================================================
--- php/php-src/trunk/Zend/tests/bug52361.phpt                          (rev 0)
+++ php/php-src/trunk/Zend/tests/bug52361.phpt  2010-08-16 09:20:46 UTC (rev 
302323)
@@ -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}
+

Modified: php/php-src/trunk/Zend/zend_objects.c
===================================================================
--- php/php-src/trunk/Zend/zend_objects.c       2010-08-16 09:13:21 UTC (rev 
302322)
+++ php/php-src/trunk/Zend/zend_objects.c       2010-08-16 09:20:46 UTC (rev 
302323)
@@ -117,15 +117,13 @@
                                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;
                        }

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to