summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXinchen Hui <laruence@php.net>2015-07-02 18:43:06 +0800
committerXinchen Hui <laruence@php.net>2015-07-02 18:43:06 +0800
commit72b0627315e6606310c1042a51dad6e835620bab (patch)
treea15c4f11e5361607d663234af1c6afd97b61c6c0
parent3422fb57c88cdb82868b845e0690569c376f080c (diff)
downloadphp-git-72b0627315e6606310c1042a51dad6e835620bab.tar.gz
Fixed bug #69521 (Segfault in gc_collect_cycles()).
-rw-r--r--NEWS8
-rw-r--r--Zend/zend_hash.c5
-rw-r--r--Zend/zend_objects.c2
-rw-r--r--Zend/zend_variables.c8
-rw-r--r--ext/standard/streamsfuncs.c13
-rw-r--r--ext/standard/tests/streams/bug69521.phpt34
6 files changed, 48 insertions, 22 deletions
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--
+<?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