dmitry                                   Tue, 11 May 2010 16:09:43 +0000

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

Log:
Fixed bug #49893 (Crash while creating an instance of Zend_Mail_Storage_Pop3)

Bug: http://bugs.php.net/49893 (Assigned) Apache 2.2 Child crash while creating 
an instance of Zend_Mail_Storage_Pop3
      
Changed paths:
    U   php/php-src/branches/PHP_5_3/NEWS
    A   php/php-src/branches/PHP_5_3/Zend/tests/bug49893.phpt
    U   php/php-src/branches/PHP_5_3/Zend/zend_objects.c
    A   php/php-src/trunk/Zend/tests/bug49893.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-05-11 15:55:07 UTC (rev 299253)
+++ php/php-src/branches/PHP_5_3/NEWS   2010-05-11 16:09:43 UTC (rev 299254)
@@ -129,6 +129,8 @@
 - Fixed bug #50383 (Exceptions thrown in __call / __callStatic do not include
   file and line in trace). (Felipe)
 - Fixed bug #50358 (Compile failure compiling ext/phar/util.lo). (Felipe)
+- Fixed bug #49893 (Crash while creating an instance of 
Zend_Mail_Storage_Pop3).
+  (Dmitry)
 - Fixed bug #49778 (DateInterval::format("%a") is always zero when an interval
   is created from an ISO string). (Derick)
 - Fixed bug #49700 (memory leaks in php_date.c if garbage collector is

Added: php/php-src/branches/PHP_5_3/Zend/tests/bug49893.phpt
===================================================================
--- php/php-src/branches/PHP_5_3/Zend/tests/bug49893.phpt                       
        (rev 0)
+++ php/php-src/branches/PHP_5_3/Zend/tests/bug49893.phpt       2010-05-11 
16:09:43 UTC (rev 299254)
@@ -0,0 +1,28 @@
+--TEST--
+Bug #49893 (Crash while creating an instance of Zend_Mail_Storage_Pop3)
+--FILE--
+<?php
+class A {
+       function __destruct() {
+               try {
+                       throw new Exception("2");
+               } catch (Exception $e) {
+                       echo $e->getMessage() . "\n";
+               }
+       }
+}
+class B {
+       function __construct() {
+               $this->a = new A();
+               throw new Exception("1");
+       }
+}
+try {
+       $b = new B();
+} catch(Exception $e) {
+       echo $e->getMessage() . "\n";;
+}
+?>
+--EXPECT--
+2
+1

Modified: php/php-src/branches/PHP_5_3/Zend/zend_objects.c
===================================================================
--- php/php-src/branches/PHP_5_3/Zend/zend_objects.c    2010-05-11 15:55:07 UTC 
(rev 299253)
+++ php/php-src/branches/PHP_5_3/Zend/zend_objects.c    2010-05-11 16:09:43 UTC 
(rev 299254)
@@ -52,6 +52,7 @@
        zend_function *destructor = object ? object->ce->destructor : NULL;

        if (destructor) {
+               zval *old_exception;
                zval *obj;
                zend_object_store_bucket *obj_bucket;

@@ -99,12 +100,25 @@
                 * For example, if an exception was thrown in a function and 
when the function's
                 * local variable destruction results in a destructor being 
called.
                 */
-               if (EG(exception) && Z_OBJ_HANDLE_P(EG(exception)) == handle) {
-                       zend_error(E_ERROR, "Attempt to destruct pending 
exception");
+               old_exception = NULL;
+               if (EG(exception)) {
+                       if (Z_OBJ_HANDLE_P(EG(exception)) == handle) {
+                               zend_error(E_ERROR, "Attempt to destruct 
pending exception");
+                       } else {
+                               old_exception = EG(exception);
+                               Z_ADDREF_P(old_exception);
+                       }
                }
                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);
+                       } else {
+                               EG(exception) = old_exception;
+                       }
+               }
                zval_ptr_dtor(&obj);
        }
 }

Added: php/php-src/trunk/Zend/tests/bug49893.phpt
===================================================================
--- php/php-src/trunk/Zend/tests/bug49893.phpt                          (rev 0)
+++ php/php-src/trunk/Zend/tests/bug49893.phpt  2010-05-11 16:09:43 UTC (rev 
299254)
@@ -0,0 +1,28 @@
+--TEST--
+Bug #49893 (Crash while creating an instance of Zend_Mail_Storage_Pop3)
+--FILE--
+<?php
+class A {
+       function __destruct() {
+               try {
+                       throw new Exception("2");
+               } catch (Exception $e) {
+                       echo $e->getMessage() . "\n";
+               }
+       }
+}
+class B {
+       function __construct() {
+               $this->a = new A();
+               throw new Exception("1");
+       }
+}
+try {
+       $b = new B();
+} catch(Exception $e) {
+       echo $e->getMessage() . "\n";;
+}
+?>
+--EXPECT--
+2
+1

Modified: php/php-src/trunk/Zend/zend_objects.c
===================================================================
--- php/php-src/trunk/Zend/zend_objects.c       2010-05-11 15:55:07 UTC (rev 
299253)
+++ php/php-src/trunk/Zend/zend_objects.c       2010-05-11 16:09:43 UTC (rev 
299254)
@@ -52,6 +52,7 @@
        zend_function *destructor = object ? object->ce->destructor : NULL;

        if (destructor) {
+               zval *old_exception;
                zval *obj;
                zend_object_store_bucket *obj_bucket;

@@ -99,12 +100,25 @@
                 * For example, if an exception was thrown in a function and 
when the function's
                 * local variable destruction results in a destructor being 
called.
                 */
-               if (EG(exception) && Z_OBJ_HANDLE_P(EG(exception)) == handle) {
-                       zend_error(E_ERROR, "Attempt to destruct pending 
exception");
+               old_exception = NULL;
+               if (EG(exception)) {
+                       if (Z_OBJ_HANDLE_P(EG(exception)) == handle) {
+                               zend_error(E_ERROR, "Attempt to destruct 
pending exception");
+                       } else {
+                               old_exception = EG(exception);
+                               Z_ADDREF_P(old_exception);
+                       }
                }
                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);
+                       } else {
+                               EG(exception) = old_exception;
+                       }
+               }
                zval_ptr_dtor(&obj);
        }
 }

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

Reply via email to