Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:4909 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 31458 invoked by uid 1010); 22 Oct 2003 06:42:37 -0000 Delivered-To: ezmlm-scan-internals@lists.php.net Delivered-To: ezmlm-internals@lists.php.net Received: (qmail 31433 invoked from network); 22 Oct 2003 06:42:36 -0000 Received: from unknown (HELO sofia.digsys.bg) (193.68.3.250) by pb1.pair.com with SMTP; 22 Oct 2003 06:42:36 -0000 Received: from damagegqsaogpp (bourgas34.pip.digsys.bg [193.68.8.34]) by sofia.digsys.bg (8.11.6/8.10.1) with SMTP id h9M6gVp20446 for ; Wed, 22 Oct 2003 09:42:31 +0300 (EEST) To: "PHP-DEV" Date: Wed, 22 Oct 2003 09:43:39 +0300 Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit X-Priority: 3 (Normal) X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook IMO, Build 9.0.2416 (9.0.2910.0) Importance: Normal X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2600.0000 Subject: [PATCH] Two bugs in variable destruction From: vma1@abv.bg ("Vesselin Atanasov") 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: 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: 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); }