# [PATCH] Two bugs in variable destruction

- Thread: https://externals.io/message/4909
- Original archive: https://news-web.php.net/php.internals/4909
- Started by Vesselin Atanasov on 2003-10-22T06:43:39+00:00
- Messages: 1
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #4909 — Vesselin Atanasov — 2003-10-22T06:43:39+00:00

URL: https://externals.io/message/4909#4909

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