From 72b0627315e6606310c1042a51dad6e835620bab Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Thu, 2 Jul 2015 18:43:06 +0800 Subject: [PATCH] Fixed bug #69521 (Segfault in gc_collect_cycles()). --- NEWS | 8 ++++-- Zend/zend_hash.c | 5 +++- Zend/zend_objects.c | 2 -- Zend/zend_variables.c | 8 ------ ext/standard/streamsfuncs.c | 13 +++------ ext/standard/tests/streams/bug69521.phpt | 34 ++++++++++++++++++++++++ 6 files changed, 48 insertions(+), 22 deletions(-) create mode 100644 ext/standard/tests/streams/bug69521.phpt diff --git a/NEWS b/NEWS index a391503c5c..b42ef01df9 100644 --- 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: 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-- + +--EXPECT-- +Sending bug 69521 -- 2.40.0