[PATCH] Two bugs in variable destruction

From: Date: Wed, 22 Oct 2003 06:43:39 +0000
Subject: [PATCH] Two bugs in variable destruction
Groups: php.internals 
Request: Send a blank email to internals+get-4909@lists.php.net to get a copy of this message
Hello. There are two bugs that show when code is executed from an object destructor and PHP is compiled in debug mode. Both bugs cause the zend_hash_find() to fail in the IS_CONSISTENT() macro. The first bug shows when the global symtable is destroyed and the destruction of a symbol causes an object destruction. If the object destructor tries to access a global symbol the zend_hash_find, IS_CONSISTENT() check will fail and error message will be logged. Here is code that shows the bug: <? class lala { public function __destruct () { global $abc; printf ("%s\n", $abc); } } $obj = new lala (); $abc = "123"; ?> The second bug shows when the object properties hash is destroyed. If the destruction of some property causes a destructor of a second object to be called and that destructor tries to access aproperty of the first object being destroyed zend_hash_find() will fail for the same reason as in first bug. Here is sample code: <? class A { private $objref; public $val; public function __construct () { $this->obref = new B (); $this->val = "msg"; } } class B { public function __destruct () { global $gA; printf ("%s\n", $gA->val); } } $gA = new A (); ?> And here is a patch that fixes these two bugs: diff -ruN php5-200310182330.orig/Zend/zend_execute_API.c php5-200310182330/Zend/zend_execute_API.c --- php5-200310182330.orig/Zend/zend_execute_API.c 2003-10-14 15:07:10.000000000 +0000 +++ php5-200310182330/Zend/zend_execute_API.c 2003-10-22 09:10:20.000000000 +0000 @@ -207,7 +207,13 @@ */ zend_llist_apply(&zend_extensions, (llist_apply_func_t) zend_extension_deactivator TSRMLS_CC); - zend_hash_destroy(&EG(symbol_table)); +/* We need to use graceful destroy here because of the following problem when + Zend engine iscompiled in debug mode. Suppose the destruction of the + symtable causes the destruction of some object. If the destructor of that + object tries to access some global variable, it will fail because the + symtable hash is in inconsistent state and Zend engine will bail out in + IS_CONSISTENT() */ + zend_hash_graceful_destroy(&EG(symbol_table)); } zend_end_try(); zend_try { diff -ruN php5-200310182330.orig/Zend/zend_objects.c php5-200310182330/Zend/zend_objects.c --- php5-200310182330.orig/Zend/zend_objects.c 2003-09-02 15:06:33.000000000 +0000 +++ php5-200310182330/Zend/zend_objects.c 2003-10-22 09:13:02.000000000 +0000 @@ -26,7 +26,13 @@ static inline void zend_nuke_object(zend_object *object TSRMLS_DC) { - zend_hash_destroy(object->properties); +/* We need to use graceful destroy here because of the following problem when + Zend engine is compiled in debug mode. Suppose the destruction of some + property invokes a destructor which possibly calls other functions and + that call chain at some place tries to access a property of the nuked + object. The access will fail because the properties hash is in + inconsistent state and Zend engine will bail out in IS_CONSISTENT () */ + zend_hash_graceful_destroy(object->properties); FREE_HASHTABLE(object->properties); efree(object); }

« previous php.internals (#4909) next »