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