dmitry                                   Fri, 15 Apr 2011 12:43:20 +0000

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

Log:
Fixed bug #54268 (Double free when destroy_zend_class fails)

Bug: http://bugs.php.net/54268 (error getting bug information)
      
Changed paths:
    A   php/php-src/branches/PHP_5_3/Zend/tests/bug54268.phpt
    U   php/php-src/branches/PHP_5_3/Zend/zend_execute_API.c
    U   php/php-src/branches/PHP_5_3/Zend/zend_hash.c
    A   php/php-src/trunk/Zend/tests/bug54268.phpt
    U   php/php-src/trunk/Zend/zend_execute_API.c
    U   php/php-src/trunk/Zend/zend_hash.c

Added: php/php-src/branches/PHP_5_3/Zend/tests/bug54268.phpt
===================================================================
--- php/php-src/branches/PHP_5_3/Zend/tests/bug54268.phpt                       
        (rev 0)
+++ php/php-src/branches/PHP_5_3/Zend/tests/bug54268.phpt       2011-04-15 
12:43:20 UTC (rev 310235)
@@ -0,0 +1,35 @@
+--TEST--
+Bug #54268 (Double free when destroy_zend_class fails)
+--INI--
+memory_limit=8M
+--SKIPIF--
+<?php
+$zend_mm_enabled = getenv("USE_ZEND_ALLOC");
+if ($zend_mm_enabled === "0") {
+       die("skip Zend MM disabled");
+}
+?>
+--FILE--
+<?php
+class DestructableObject
+{
+        public function __destruct()
+        {
+                DestructableObject::__destruct();
+        }
+}
+class DestructorCreator
+{
+        public function __destruct()
+        {
+                $this->test = new DestructableObject;
+        }
+}
+class Test
+{
+        public static $mystatic;
+}
+$x = new Test();
+Test::$mystatic = new DestructorCreator();
+--EXPECTF--
+Fatal error: Allowed memory size of %s bytes exhausted%s(tried to allocate %s 
bytes) in %s on line %d

Modified: php/php-src/branches/PHP_5_3/Zend/zend_execute_API.c
===================================================================
--- php/php-src/branches/PHP_5_3/Zend/zend_execute_API.c        2011-04-15 
12:05:45 UTC (rev 310234)
+++ php/php-src/branches/PHP_5_3/Zend/zend_execute_API.c        2011-04-15 
12:43:20 UTC (rev 310235)
@@ -296,7 +296,9 @@
                        zend_hash_reverse_apply(EG(function_table), 
(apply_func_t) zend_cleanup_function_data TSRMLS_CC);
                }
                zend_hash_apply(EG(class_table), (apply_func_t) 
zend_cleanup_class_data TSRMLS_CC);
+       } zend_end_try();

+       zend_try {
                zend_vm_stack_destroy(TSRMLS_C);

                zend_objects_store_free_object_storage(&EG(objects_store) 
TSRMLS_CC);

Modified: php/php-src/branches/PHP_5_3/Zend/zend_hash.c
===================================================================
--- php/php-src/branches/PHP_5_3/Zend/zend_hash.c       2011-04-15 12:05:45 UTC 
(rev 310234)
+++ php/php-src/branches/PHP_5_3/Zend/zend_hash.c       2011-04-15 12:43:20 UTC 
(rev 310235)
@@ -545,9 +545,15 @@

        IS_CONSISTENT(ht);

-       SET_INCONSISTENT(HT_CLEANING);
-
        p = ht->pListHead;
+
+       memset(ht->arBuckets, 0, ht->nTableSize*sizeof(Bucket *));
+       ht->pListHead = NULL;
+       ht->pListTail = NULL;
+       ht->nNumOfElements = 0;
+       ht->nNextFreeElement = 0;
+       ht->pInternalPointer = NULL;
+
        while (p != NULL) {
                q = p;
                p = p->pListNext;
@@ -559,14 +565,6 @@
                }
                pefree(q, ht->persistent);
        }
-       memset(ht->arBuckets, 0, ht->nTableSize*sizeof(Bucket *));
-       ht->pListHead = NULL;
-       ht->pListTail = NULL;
-       ht->nNumOfElements = 0;
-       ht->nNextFreeElement = 0;
-       ht->pInternalPointer = NULL;
-
-       SET_INCONSISTENT(HT_OK);
 }

 /* This function is used by the various apply() functions.

Added: php/php-src/trunk/Zend/tests/bug54268.phpt
===================================================================
--- php/php-src/trunk/Zend/tests/bug54268.phpt                          (rev 0)
+++ php/php-src/trunk/Zend/tests/bug54268.phpt  2011-04-15 12:43:20 UTC (rev 
310235)
@@ -0,0 +1,35 @@
+--TEST--
+Bug #54268 (Double free when destroy_zend_class fails)
+--INI--
+memory_limit=8M
+--SKIPIF--
+<?php
+$zend_mm_enabled = getenv("USE_ZEND_ALLOC");
+if ($zend_mm_enabled === "0") {
+       die("skip Zend MM disabled");
+}
+?>
+--FILE--
+<?php
+class DestructableObject
+{
+        public function __destruct()
+        {
+                DestructableObject::__destruct();
+        }
+}
+class DestructorCreator
+{
+        public function __destruct()
+        {
+                $this->test = new DestructableObject;
+        }
+}
+class Test
+{
+        public static $mystatic;
+}
+$x = new Test();
+Test::$mystatic = new DestructorCreator();
+--EXPECTF--
+Fatal error: Allowed memory size of %s bytes exhausted%s(tried to allocate %s 
bytes) in %s on line %d

Modified: php/php-src/trunk/Zend/zend_execute_API.c
===================================================================
--- php/php-src/trunk/Zend/zend_execute_API.c   2011-04-15 12:05:45 UTC (rev 
310234)
+++ php/php-src/trunk/Zend/zend_execute_API.c   2011-04-15 12:43:20 UTC (rev 
310235)
@@ -289,7 +289,9 @@
                        zend_hash_reverse_apply(EG(class_table), (apply_func_t) 
zend_cleanup_user_class_data TSRMLS_CC);
                        zend_cleanup_internal_classes(TSRMLS_C);
                }
+       } zend_end_try();

+       zend_try {
                zend_vm_stack_destroy(TSRMLS_C);

                zend_objects_store_free_object_storage(&EG(objects_store) 
TSRMLS_CC);

Modified: php/php-src/trunk/Zend/zend_hash.c
===================================================================
--- php/php-src/trunk/Zend/zend_hash.c  2011-04-15 12:05:45 UTC (rev 310234)
+++ php/php-src/trunk/Zend/zend_hash.c  2011-04-15 12:43:20 UTC (rev 310235)
@@ -563,9 +563,17 @@

        IS_CONSISTENT(ht);

-       SET_INCONSISTENT(HT_CLEANING);
-
        p = ht->pListHead;
+
+       if (ht->nTableMask) {
+               memset(ht->arBuckets, 0, ht->nTableSize*sizeof(Bucket *));
+       }
+       ht->pListHead = NULL;
+       ht->pListTail = NULL;
+       ht->nNumOfElements = 0;
+       ht->nNextFreeElement = 0;
+       ht->pInternalPointer = NULL;
+
        while (p != NULL) {
                q = p;
                p = p->pListNext;
@@ -577,16 +585,6 @@
                }
                pefree(q, ht->persistent);
        }
-       if (ht->nTableMask) {
-               memset(ht->arBuckets, 0, ht->nTableSize*sizeof(Bucket *));
-       }
-       ht->pListHead = NULL;
-       ht->pListTail = NULL;
-       ht->nNumOfElements = 0;
-       ht->nNextFreeElement = 0;
-       ht->pInternalPointer = NULL;
-
-       SET_INCONSISTENT(HT_OK);
 }

 /* This function is used by the various apply() functions.

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

Reply via email to