]> granicus.if.org Git - php/commitdiff
Preserve keys in emulate_read_fd_set()
authortwosee <twose@qq.com>
Mon, 8 Apr 2019 10:58:46 +0000 (12:58 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Mon, 8 Apr 2019 10:58:46 +0000 (12:58 +0200)
Keys are already preserved in the non-emulated case.

ext/standard/streamsfuncs.c
ext/standard/tests/streams/stream_select_preserve_keys.phpt [new file with mode: 0644]

index 265438290635f80a6a29e38e467e8aa93fed7e77..9d725db919371acabfa32bdccdc52ed1a701d4e5 100644 (file)
@@ -710,6 +710,8 @@ static int stream_array_emulate_read_fd_set(zval *stream_array)
        zval *elem, *dest_elem, new_array;
        php_stream *stream;
        int ret = 0;
+       zend_ulong num_ind;
+       zend_string *key;
 
        if (Z_TYPE_P(stream_array) != IS_ARRAY) {
                return 0;
@@ -717,7 +719,7 @@ static int stream_array_emulate_read_fd_set(zval *stream_array)
        ZVAL_NEW_ARR(&new_array);
        zend_hash_init(Z_ARRVAL(new_array), zend_hash_num_elements(Z_ARRVAL_P(stream_array)), NULL, ZVAL_PTR_DTOR, 0);
 
-       ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(stream_array), elem) {
+       ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(stream_array), num_ind, key, elem) {
                ZVAL_DEREF(elem);
                php_stream_from_zval_no_verify(stream, elem);
                if (stream == NULL) {
@@ -730,10 +732,12 @@ static int stream_array_emulate_read_fd_set(zval *stream_array)
                         * This branch of code also allows blocking streams with buffered data to
                         * operate correctly in stream_select.
                         * */
-                       dest_elem = zend_hash_next_index_insert(Z_ARRVAL(new_array), elem);
-                       if (dest_elem) {
-                               zval_add_ref(dest_elem);
+                       if (!key) {
+                               dest_elem = zend_hash_index_update(Z_ARRVAL(new_array), num_ind, elem);
+                       } else {
+                               dest_elem = zend_hash_update(Z_ARRVAL(new_array), key, elem);
                        }
+                       zval_add_ref(dest_elem);
                        ret++;
                        continue;
                }
diff --git a/ext/standard/tests/streams/stream_select_preserve_keys.phpt b/ext/standard/tests/streams/stream_select_preserve_keys.phpt
new file mode 100644 (file)
index 0000000..390709f
--- /dev/null
@@ -0,0 +1,35 @@
+--TEST--
+Bug #53427 + emulate_read (stream_select does not preserve keys)
+--FILE--
+<?php
+$read[1] = fopen(__FILE__, 'r');
+$read['myindex'] = reset($read);
+$write = NULL;
+$except = NULL;
+
+var_dump($read);
+stream_select($read, $write, $except, 0);
+var_dump($read);
+fread(reset($read), 1);
+stream_select($read, $write, $except, 0); // // emulate_read
+var_dump($read);
+?>
+--EXPECTF--
+array(2) {
+  [1]=>
+  resource(%d) of type (stream)
+  ["myindex"]=>
+  resource(%d) of type (stream)
+}
+array(2) {
+  [1]=>
+  resource(%d) of type (stream)
+  ["myindex"]=>
+  resource(%d) of type (stream)
+}
+array(2) {
+  [1]=>
+  resource(%d) of type (stream)
+  ["myindex"]=>
+  resource(%d) of type (stream)
+}