From: Dmitry Stogov Date: Fri, 15 Apr 2011 12:43:20 +0000 (+0000) Subject: Fixed bug #54268 (Double free when destroy_zend_class fails) X-Git-Tag: php-5.4.0alpha1~191^2~66 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=50ce16deff058dfbf2a04113e4bad1548521bc64;p=php Fixed bug #54268 (Double free when destroy_zend_class fails) --- diff --git a/Zend/tests/bug54268.phpt b/Zend/tests/bug54268.phpt new file mode 100644 index 0000000000..b544cd882a --- /dev/null +++ b/Zend/tests/bug54268.phpt @@ -0,0 +1,35 @@ +--TEST-- +Bug #54268 (Double free when destroy_zend_class fails) +--INI-- +memory_limit=8M +--SKIPIF-- + +--FILE-- +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 diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 03d250cce7..e15344a4f0 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -289,7 +289,9 @@ void shutdown_executor(TSRMLS_D) /* {{{ */ 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); diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c index 4ee3cdeb5c..73c45a286c 100644 --- a/Zend/zend_hash.c +++ b/Zend/zend_hash.c @@ -563,9 +563,17 @@ ZEND_API void zend_hash_clean(HashTable *ht) 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 @@ ZEND_API void zend_hash_clean(HashTable *ht) } 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.