summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGustavo André dos Santos Lopes <cataphract@php.net>2010-11-30 16:22:48 +0000
committerGustavo André dos Santos Lopes <cataphract@php.net>2010-11-30 16:22:48 +0000
commit22d461df621a1c059800a50c9d5c8bba41a14f16 (patch)
treea05c849788e65159e7c43f643b36e2124a0cc6d3
parentc579738b9419d035967509cf3216e55d61f4c2fa (diff)
downloadphp-git-22d461df621a1c059800a50c9d5c8bba41a14f16.tar.gz
- Implemented bug/request #53427 - stream_select doesn't preserve the
keys. This cannot be backported to PHP 5.3 due to a BC break. See UPGRADING for more information.
-rwxr-xr-xUPGRADING4
-rw-r--r--ext/standard/streamsfuncs.c21
-rw-r--r--ext/standard/tests/streams/bug53427.phpt27
3 files changed, 50 insertions, 2 deletions
diff --git a/UPGRADING b/UPGRADING
index d1c3357eb3..b8aad2f492 100755
--- a/UPGRADING
+++ b/UPGRADING
@@ -140,6 +140,10 @@ UPGRADE NOTES - PHP X.Y
possible value. This value results in scandir() performing no sorting: on
local filesystems, this allows files to be returned in native filesystem
order.
+- stream_select() now preserves the keys of the passed array, be they numeric or
+ strings. This breaks code that iterated the resulting stream array using a
+ numeric index, but makes easier to identify which of the passed streams are
+ present in the result.
===================================
diff --git a/ext/standard/streamsfuncs.c b/ext/standard/streamsfuncs.c
index 0ed8e10e6d..5f408f50d5 100644
--- a/ext/standard/streamsfuncs.c
+++ b/ext/standard/streamsfuncs.c
@@ -655,9 +655,21 @@ static int stream_array_from_fd_set(zval *stream_array, fd_set *fds TSRMLS_DC)
zend_hash_init(new_hash, zend_hash_num_elements(Z_ARRVAL_P(stream_array)), NULL, ZVAL_PTR_DTOR, 0);
for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(stream_array));
- zend_hash_get_current_data(Z_ARRVAL_P(stream_array), (void **) &elem) == SUCCESS;
+ zend_hash_has_more_elements(Z_ARRVAL_P(stream_array)) == SUCCESS;
zend_hash_move_forward(Z_ARRVAL_P(stream_array))) {
+ int type;
+ char *key;
+ uint key_len;
+ ulong num_ind;
+
+ type = zend_hash_get_current_key_ex(Z_ARRVAL_P(stream_array),
+ &key, &key_len, &num_ind, 0, NULL);
+ if (type == HASH_KEY_NON_EXISTANT ||
+ zend_hash_get_current_data(Z_ARRVAL_P(stream_array), (void **) &elem) == FAILURE) {
+ continue; /* should not happen */
+ }
+
php_stream_from_zval_no_verify(stream, elem);
if (stream == NULL) {
continue;
@@ -669,7 +681,12 @@ static int stream_array_from_fd_set(zval *stream_array, fd_set *fds TSRMLS_DC)
*/
if (SUCCESS == php_stream_cast(stream, PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL, (void*)&this_fd, 1) && this_fd >= 0) {
if (PHP_SAFE_FD_ISSET(this_fd, fds)) {
- zend_hash_next_index_insert(new_hash, (void *)elem, sizeof(zval *), (void **)&dest_elem);
+ if (type == HASH_KEY_IS_LONG) {
+ zend_hash_index_update(new_hash, num_ind, (void *)elem, sizeof(zval *), (void **)&dest_elem);
+ } else { /* HASH_KEY_IS_STRING */
+ zend_hash_update(new_hash, key, key_len, (void *)elem, sizeof(zval *), (void **)&dest_elem);
+ }
+
if (dest_elem) {
zval_add_ref(dest_elem);
}
diff --git a/ext/standard/tests/streams/bug53427.phpt b/ext/standard/tests/streams/bug53427.phpt
new file mode 100644
index 0000000000..9e2e037959
--- /dev/null
+++ b/ext/standard/tests/streams/bug53427.phpt
@@ -0,0 +1,27 @@
+--TEST--
+Bug #53427 (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);
+--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)
+}