]> granicus.if.org Git - php/commitdiff
Fixed bug #69521 (Segfault in gc_collect_cycles()).
authorXinchen Hui <laruence@php.net>
Thu, 2 Jul 2015 10:43:06 +0000 (18:43 +0800)
committerXinchen Hui <laruence@php.net>
Thu, 2 Jul 2015 10:43:06 +0000 (18:43 +0800)
NEWS
Zend/zend_hash.c
Zend/zend_objects.c
Zend/zend_variables.c
ext/standard/streamsfuncs.c
ext/standard/tests/streams/bug69521.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index a391503c5cf472399030dedf35446aa8c699c6e2..b42ef01df976f033e9ecb7c9c106759bada9e7a9 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -3,9 +3,9 @@ PHP                                                                        NEWS
 09 Jul 2015, PHP 7.0.0 Beta 1
 
 - Core:
-  . Fixed bug #69976 (Unable to parse "all" urls with colon char). (cmb)
+  . Fixed bug #69521 (Segfault in gc_collect_cycles()).
+    (arjen at react dot com, Laruence)
   . Improved zend_string API (Francois Laupretre)
-  . Fixed bug #69768 (escapeshell*() doesn't cater to !). (cmb)
   . Fixed bug #69955 (Segfault when trying to combine [] and assign-op on
     ArrayAccess object). (Laruence)
 
@@ -36,6 +36,10 @@ PHP                                                                        NEWS
   . Fixed bug #69952 (Data integrity issues accessing superglobals by
     reference). (Bob)
 
+- Standard:
+  . Fixed bug #69976 (Unable to parse "all" urls with colon char). (cmb)
+  . Fixed bug #69768 (escapeshell*() doesn't cater to !). (cmb)
+
 25 Jun 2015, PHP 7.0.0 Alpha 2
 
 - Core:
index a1cf8526d62913a9cc10395d69139f4d8572f7af..eb5081d56c724d942bb8cba061fa8981424f77aa 100644 (file)
@@ -1218,8 +1218,11 @@ ZEND_API void ZEND_FASTCALL zend_array_destroy(HashTable *ht)
        IS_CONSISTENT(ht);
        HT_ASSERT(GC_REFCOUNT(ht) <= 1);
 
-       if (ht->nNumUsed) {
+       /* break possible cycles */
+       GC_REMOVE_FROM_BUFFER(ht);
+       GC_TYPE_INFO(ht) = IS_NULL | (GC_WHITE << 16);
 
+       if (ht->nNumUsed) {
                /* In some rare cases destructors of regular arrays may be changed */
                if (UNEXPECTED(ht->pDestructor != ZVAL_PTR_DTOR)) {
                        zend_hash_destroy(ht);
index 9eccf1b601b74743fc3d7a877ed5e255475fd2ca..6dc1a2d07600910359253f03b895c87b7d57edd6 100644 (file)
@@ -57,8 +57,6 @@ ZEND_API void zend_object_std_dtor(zend_object *object)
        if (object->properties) {
                if (EXPECTED(!(GC_FLAGS(object->properties) & IS_ARRAY_IMMUTABLE))) {
                        if (EXPECTED(--GC_REFCOUNT(object->properties) == 0)) {
-                               GC_REMOVE_FROM_BUFFER(object->properties);
-                               GC_TYPE_INFO(object->properties) = IS_NULL | (GC_WHITE << 16);
                                zend_array_destroy(object->properties);
                        }
                }
index 58e1190fc17571383b103fde7e5c13bb1398cbb4..5f04bfc37253b75eb188aee0c76360da07b6fa0b 100644 (file)
@@ -39,12 +39,7 @@ ZEND_API void ZEND_FASTCALL _zval_dtor_func(zend_refcounted *p ZEND_FILE_LINE_DC
                        }
                case IS_ARRAY: {
                                zend_array *arr = (zend_array*)p;
-
                                ZEND_ASSERT(GC_REFCOUNT(arr) <= 1);
-
-                               /* break possible cycles */
-                               GC_REMOVE_FROM_BUFFER(arr);
-                               GC_TYPE_INFO(arr) = IS_NULL | (GC_WHITE << 16);
                                zend_array_destroy(arr);
                                break;
                        }
@@ -97,9 +92,6 @@ ZEND_API void ZEND_FASTCALL _zval_dtor_func_for_ptr(zend_refcounted *p ZEND_FILE
                case IS_ARRAY: {
                                zend_array *arr = (zend_array*)p;
 
-                               /* break possible cycles */
-                               GC_REMOVE_FROM_BUFFER(arr);
-                               GC_TYPE_INFO(arr) = IS_NULL | (GC_WHITE << 16);
                                zend_array_destroy(arr);
                                break;
                        }
index d5c3f53dc377e44d895ac26add655fe665ab9c71..a61dbffdc5e2a4254952eba7cbd577f5c416fbd3 100644 (file)
@@ -656,10 +656,7 @@ static int stream_array_from_fd_set(zval *stream_array, fd_set *fds)
        } ZEND_HASH_FOREACH_END();
 
        /* destroy old array and add new one */
-       zend_hash_destroy(Z_ARRVAL_P(stream_array));
-       GC_REMOVE_FROM_BUFFER(Z_ARR_P(stream_array));
-       efree(Z_ARR_P(stream_array));
-
+       zend_array_destroy(Z_ARR_P(stream_array));
        Z_ARR_P(stream_array) = Z_ARR(new_array);
 
        return ret;
@@ -700,12 +697,10 @@ static int stream_array_emulate_read_fd_set(zval *stream_array)
 
        if (ret > 0) {
                /* destroy old array and add new one */
-               zend_hash_destroy(Z_ARRVAL_P(stream_array));
-               efree(Z_ARR_P(stream_array));
+               zend_array_destroy(Z_ARR_P(stream_array));
                Z_ARR_P(stream_array) = Z_ARR(new_array);
        } else {
-               zend_hash_destroy(Z_ARRVAL(new_array));
-               efree(Z_ARR(new_array));
+               zend_array_destroy(Z_ARR(new_array));
        }
 
        return ret;
@@ -1020,7 +1015,7 @@ PHP_FUNCTION(stream_context_set_params)
    Get parameters of a file context */
 PHP_FUNCTION(stream_context_get_params)
 {
-       zval *zcontext, options;
+       zval *zcontext;
        php_stream_context *context;
 
        if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &zcontext) == FAILURE) {
diff --git a/ext/standard/tests/streams/bug69521.phpt b/ext/standard/tests/streams/bug69521.phpt
new file mode 100644 (file)
index 0000000..b5429d4
--- /dev/null
@@ -0,0 +1,34 @@
+--TEST--
+Bug #69521     Segfault in gc_collect_cycles()
+--FILE--
+<?php
+$serverUri = "tcp://127.0.0.1:64321";
+$sock = stream_socket_server($serverUri, $errno, $errstr, STREAM_SERVER_BIND | STREAM_SERVER_LISTEN);
+
+$fp = stream_socket_client($serverUri, $errNumber, $errString, 5, STREAM_CLIENT_CONNECT);
+
+$written = 0;
+
+$data = "test";
+$written += fwrite($fp, substr($data, $written, 100));
+
+$link = stream_socket_accept($sock);
+fread($link, 1000);
+fwrite($link, "Sending bug 69521\n");
+fclose($link);
+
+while (!feof($fp))
+{
+       $read = $write = array($fp);
+
+       if ($written === strlen($data))
+               $write = array();
+
+       $changed = stream_select($read, $write, $except, 0, 500000);
+
+       if (!empty($read))
+               echo fread($fp, 4);
+}
+?>
+--EXPECT--
+Sending bug 69521