]> granicus.if.org Git - php/commitdiff
Fix #79247: Garbage collecting variant objects segfaults
authorChristoph M. Becker <cmbecker69@gmx.de>
Sat, 8 Feb 2020 09:58:15 +0000 (10:58 +0100)
committerChristoph M. Becker <cmbecker69@gmx.de>
Sat, 8 Feb 2020 10:03:52 +0000 (11:03 +0100)
variant objects have no (declared) properties, so the `get_properties`
handlers returns a pointer to constant storage for efficiency reasons.
This pointer must not be returned from the `get_gc` handler, though;
instead we set up an own `get_gc` handler and return NULL from it, to
signal that there are no properties to collect.

NEWS
ext/com_dotnet/bug79247.phpt [new file with mode: 0644]
ext/com_dotnet/com_handlers.c

diff --git a/NEWS b/NEWS
index 8dbff5e134f038cce84622ac49f1c05c799cec6b..bbd7af4f69d551800b3e6339582dcd255e13882f 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -8,6 +8,7 @@ PHP                                                                        NEWS
     (cmb)
   . Fixed bug #79242 (COM error constants don't match com_exception codes on
     x86). (cmb)
+  . Fixed bug #79247 (Garbage collecting variant objects segfaults). (cmb)
 
 - CURL:
   . Fixed bug #79019 (Copied cURL handles upload empty file). (cmb)
diff --git a/ext/com_dotnet/bug79247.phpt b/ext/com_dotnet/bug79247.phpt
new file mode 100644 (file)
index 0000000..55e24b1
--- /dev/null
@@ -0,0 +1,13 @@
+--TEST--
+Bug #79247 (Garbage collecting variant objects segfaults)
+--SKIPIF--
+<?php
+if (!extension_loaded('com_dotnet')) die('skip com_dotnet extension not available');
+?>
+--FILE--
+<?php
+$keep = new variant(null);
+var_dump(gc_collect_cycles());
+?>
+--EXPECT--
+int(0)
index fe39e2f9e049d2d61bc2b10afb8c2457cf8e0db2..d42e7453f863383b02f3ab5f958abbb4d80a861c 100644 (file)
@@ -243,6 +243,13 @@ static HashTable *com_properties_get(zval *object)
        return &zend_empty_array;
 }
 
+static HashTable *com_get_gc(zval *object, zval **table, int *n)
+{
+       *table = NULL;
+       *n = 0;
+       return NULL;
+}
+
 static void function_dtor(zval *zv)
 {
        zend_internal_function *f = (zend_internal_function*)Z_PTR_P(zv);
@@ -573,7 +580,7 @@ zend_object_handlers php_com_object_handlers = {
        com_object_count,
        NULL,                                                                   /* get_debug_info */
        NULL,                                                                   /* get_closure */
-       zend_std_get_gc,                                                /* get_gc */
+       com_get_gc,                                                             /* get_gc */
 };
 
 void php_com_object_enable_event_sink(php_com_dotnet_object *obj, int enable)