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);
 }

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to