diff options
author | Xinchen Hui <laruence@php.net> | 2015-07-02 18:43:06 +0800 |
---|---|---|
committer | Xinchen Hui <laruence@php.net> | 2015-07-02 18:43:06 +0800 |
commit | 72b0627315e6606310c1042a51dad6e835620bab (patch) | |
tree | a15c4f11e5361607d663234af1c6afd97b61c6c0 | |
parent | 3422fb57c88cdb82868b845e0690569c376f080c (diff) | |
download | php-git-72b0627315e6606310c1042a51dad6e835620bab.tar.gz |
Fixed bug #69521 (Segfault in gc_collect_cycles()).
-rw-r--r-- | NEWS | 8 | ||||
-rw-r--r-- | Zend/zend_hash.c | 5 | ||||
-rw-r--r-- | Zend/zend_objects.c | 2 | ||||
-rw-r--r-- | Zend/zend_variables.c | 8 | ||||
-rw-r--r-- | ext/standard/streamsfuncs.c | 13 | ||||
-rw-r--r-- | ext/standard/tests/streams/bug69521.phpt | 34 |
6 files changed, 48 insertions, 22 deletions
@@ -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: diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c index a1cf8526d6..eb5081d56c 100644 --- a/Zend/zend_hash.c +++ b/Zend/zend_hash.c @@ -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); diff --git a/Zend/zend_objects.c b/Zend/zend_objects.c index 9eccf1b601..6dc1a2d076 100644 --- a/Zend/zend_objects.c +++ b/Zend/zend_objects.c @@ -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); } } diff --git a/Zend/zend_variables.c b/Zend/zend_variables.c index 58e1190fc1..5f04bfc372 100644 --- a/Zend/zend_variables.c +++ b/Zend/zend_variables.c @@ -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; } diff --git a/ext/standard/streamsfuncs.c b/ext/standard/streamsfuncs.c index d5c3f53dc3..a61dbffdc5 100644 --- a/ext/standard/streamsfuncs.c +++ b/ext/standard/streamsfuncs.c @@ -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 index 0000000000..b5429d4f45 --- /dev/null +++ b/ext/standard/tests/streams/bug69521.phpt @@ -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 |