]> granicus.if.org Git - php/commitdiff
fix #49192 - crash in GC when get_properties handler returns null
authorStanislav Malyshev <stas@php.net>
Thu, 1 Apr 2010 22:54:03 +0000 (22:54 +0000)
committerStanislav Malyshev <stas@php.net>
Thu, 1 Apr 2010 22:54:03 +0000 (22:54 +0000)
NEWS
Zend/zend_gc.c
ext/com_dotnet/tests/bug49192.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 513489aded1df7bb8d302000e9df599f0b4931d3..326830246f426441c94c7bf525f8b22bb678bce7 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -51,6 +51,7 @@ PHP                                                                        NEWS
 - Fixed bug #49778 (DateInterval::format("%a") is always zero when an interval
   is created from an ISO string). (Derick)
 - Fixed bug #49429 (odbc_autocommit doesn't work). (Felipe)
+- Fixed bug #49192 (PHP crashes when GC invoked on COM object). (Stas)
 - Fixed bug #49059 (DateTime::diff() repeats previous sub() operation).
   (yoarvi@gmail.com, Derick)
 - Fixed bug #48902 (Timezone database fallback map is outdated). (Derick)
index ab1e12a13b9d66e28b380f262789b2db0ceff7e0..db04652f09bc2e1a46532a46b134801fd758d2cc 100644 (file)
@@ -282,7 +282,11 @@ tail_call:
                        GC_SET_BLACK(obj->buffered);
                        if (EXPECTED(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(pz)].valid &&
                                     Z_OBJ_HANDLER_P(pz, get_properties) != NULL)) {
-                               p = Z_OBJPROP_P(pz)->pListHead;
+                               HashTable *props = Z_OBJPROP_P(pz);
+                               if(!props) {
+                                       return;
+                               }
+                               p = props->pListHead;
                        }
                }
        } else if (Z_TYPE_P(pz) == IS_ARRAY) {
@@ -313,7 +317,11 @@ static void zobj_scan_black(struct _store_object *obj, zval *pz TSRMLS_DC)
        GC_SET_BLACK(obj->buffered);
        if (EXPECTED(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(pz)].valid &&
                     Z_OBJ_HANDLER_P(pz, get_properties) != NULL)) {
-               p = Z_OBJPROP_P(pz)->pListHead;
+               HashTable *props = Z_OBJPROP_P(pz);
+               if(!props) {
+                       return;
+               }
+               p = props->pListHead;
                while (p != NULL) {
                        pz = *(zval**)p->pData;
                        if (Z_TYPE_P(pz) != IS_ARRAY || Z_ARRVAL_P(pz) != &EG(symbol_table)) {
@@ -346,7 +354,11 @@ tail_call:
                                GC_SET_COLOR(obj->buffered, GC_GREY);
                                if (EXPECTED(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(pz)].valid &&
                                             Z_OBJ_HANDLER_P(pz, get_properties) != NULL)) {
-                                       p = Z_OBJPROP_P(pz)->pListHead;
+                                       HashTable *props = Z_OBJPROP_P(pz);
+                                       if(!props) {
+                                               return;
+                                       }
+                                       p = props->pListHead;
                                }
                        }
                } else if (Z_TYPE_P(pz) == IS_ARRAY) {
@@ -380,7 +392,11 @@ static void zobj_mark_grey(struct _store_object *obj, zval *pz TSRMLS_DC)
                GC_SET_COLOR(obj->buffered, GC_GREY);
                if (EXPECTED(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(pz)].valid &&
                             Z_OBJ_HANDLER_P(pz, get_properties) != NULL)) {
-                       p = Z_OBJPROP_P(pz)->pListHead;
+                       HashTable *props = Z_OBJPROP_P(pz);
+                       if(!props) {
+                               return;
+                       }
+                       p = props->pListHead;
                        while (p != NULL) {
                                pz = *(zval**)p->pData;
                                if (Z_TYPE_P(pz) != IS_ARRAY || Z_ARRVAL_P(pz) != &EG(symbol_table)) {
@@ -445,7 +461,11 @@ tail_call:
                                                GC_SET_COLOR(obj->buffered, GC_WHITE);
                                                if (EXPECTED(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(pz)].valid &&
                                                             Z_OBJ_HANDLER_P(pz, get_properties) != NULL)) {
-                                                       p = Z_OBJPROP_P(pz)->pListHead;
+                                                       HashTable *props = Z_OBJPROP_P(pz);
+                                                       if(!props) {
+                                                               return 0;
+                                                       }
+                                                       p = props->pListHead;
                                                }
                                        }
                                }
@@ -484,7 +504,11 @@ static void zobj_scan(zval *pz TSRMLS_DC)
                                GC_SET_COLOR(obj->buffered, GC_WHITE);
                                if (EXPECTED(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(pz)].valid &&
                                             Z_OBJ_HANDLER_P(pz, get_properties) != NULL)) {
-                                       p = Z_OBJPROP_P(pz)->pListHead;
+                                       HashTable *props = Z_OBJPROP_P(pz);
+                                       if(!props) {
+                                               return;
+                                       }
+                                       p = props->pListHead;
                                        while (p != NULL) {
                                                zval_scan(*(zval**)p->pData TSRMLS_CC);
                                                p = p->pListNext;
@@ -531,7 +555,11 @@ tail_call:
 
                                if (EXPECTED(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(pz)].valid &&
                                             Z_OBJ_HANDLER_P(pz, get_properties) != NULL)) {
-                                       p = Z_OBJPROP_P(pz)->pListHead;
+                                       HashTable *props = Z_OBJPROP_P(pz);
+                                       if(!props) {
+                                               return;
+                                       }
+                                       p = props->pListHead;
                                }
                        }
                } else {
@@ -572,7 +600,11 @@ static void zobj_collect_white(zval *pz TSRMLS_DC)
 
                        if (EXPECTED(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(pz)].valid &&
                                     Z_OBJ_HANDLER_P(pz, get_properties) != NULL)) {
-                               p = Z_OBJPROP_P(pz)->pListHead;
+                               HashTable *props = Z_OBJPROP_P(pz);
+                               if(!props) {
+                                       return;
+                               }
+                               p = props->pListHead;
                                while (p != NULL) {
                                        pz = *(zval**)p->pData;
                                        if (Z_TYPE_P(pz) != IS_ARRAY || Z_ARRVAL_P(pz) != &EG(symbol_table)) {
diff --git a/ext/com_dotnet/tests/bug49192.phpt b/ext/com_dotnet/tests/bug49192.phpt
new file mode 100644 (file)
index 0000000..7bae1d7
--- /dev/null
@@ -0,0 +1,13 @@
+--TEST--
+Bug #49192 (PHP crashes when GC invoked on COM object)
+--SKIPIF--
+<?php 
+if (!extension_loaded("com_dotnet")) print "skip COM/.Net support not present"; ?>
+--FILE--
+<?php
+
+$dbConnection = new Com('ADODB.Connection');
+var_dump(gc_collect_cycles());
+?>
+--EXPECT--
+int(0)