summaryrefslogtreecommitdiff
path: root/ext/standard
diff options
context:
space:
mode:
authorOndřej Surý <ondrej@sury.org>2013-05-09 17:32:08 +0200
committerOndřej Surý <ondrej@sury.org>2013-05-09 17:32:08 +0200
commitd674441ee1b9e7407f464b2692d9f5a0e2be3b4e (patch)
treecc4885524786f143bcc1af7d6c3f86fb571905de /ext/standard
parent367111123281ebfd2876d4c8cf33414b394f489a (diff)
downloadphp-d674441ee1b9e7407f464b2692d9f5a0e2be3b4e.tar.gz
Imported Upstream version 5.5.0~rc1upstream/5.5.0_rc1
Diffstat (limited to 'ext/standard')
-rw-r--r--ext/standard/streamsfuncs.c21
-rw-r--r--ext/standard/tests/file/bug24482.phpt5
-rw-r--r--ext/standard/tests/streams/bug64770.phpt52
3 files changed, 74 insertions, 4 deletions
diff --git a/ext/standard/streamsfuncs.c b/ext/standard/streamsfuncs.c
index 21c55e404..209cb7f9b 100644
--- a/ext/standard/streamsfuncs.c
+++ b/ext/standard/streamsfuncs.c
@@ -601,7 +601,6 @@ static int stream_array_to_fd_set(zval *stream_array, fd_set *fds, php_socket_t
{
zval **elem;
php_stream *stream;
- php_socket_t this_fd;
int cnt = 0;
if (Z_TYPE_P(stream_array) != IS_ARRAY) {
@@ -611,6 +610,11 @@ static int stream_array_to_fd_set(zval *stream_array, fd_set *fds, php_socket_t
zend_hash_get_current_data(Z_ARRVAL_P(stream_array), (void **) &elem) == SUCCESS;
zend_hash_move_forward(Z_ARRVAL_P(stream_array))) {
+ /* Temporary int fd is needed for the STREAM data type on windows, passing this_fd directly to php_stream_cast()
+ would eventually bring a wrong result on x64. php_stream_cast() casts to int internally, and this will leave
+ the higher bits of a SOCKET variable uninitialized on systems with little endian. */
+ int tmp_fd;
+
php_stream_from_zval_no_verify(stream, elem);
if (stream == NULL) {
continue;
@@ -620,7 +624,9 @@ static int stream_array_to_fd_set(zval *stream_array, fd_set *fds, php_socket_t
* when casting. It is only used here so that the buffered data warning
* is not displayed.
* */
- if (SUCCESS == php_stream_cast(stream, PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL, (void*)&this_fd, 1) && this_fd != -1) {
+ if (SUCCESS == php_stream_cast(stream, PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL, (void*)&tmp_fd, 1) && tmp_fd != -1) {
+
+ php_socket_t this_fd = (php_socket_t)tmp_fd;
PHP_SAFE_FD_SET(this_fd, fds);
@@ -638,7 +644,6 @@ static int stream_array_from_fd_set(zval *stream_array, fd_set *fds TSRMLS_DC)
zval **elem, **dest_elem;
php_stream *stream;
HashTable *new_hash;
- php_socket_t this_fd;
int ret = 0;
if (Z_TYPE_P(stream_array) != IS_ARRAY) {
@@ -655,6 +660,11 @@ static int stream_array_from_fd_set(zval *stream_array, fd_set *fds TSRMLS_DC)
char *key;
uint key_len;
ulong num_ind;
+ /* Temporary int fd is needed for the STREAM data type on windows, passing this_fd directly to php_stream_cast()
+ would eventually bring a wrong result on x64. php_stream_cast() casts to int internally, and this will leave
+ the higher bits of a SOCKET variable uninitialized on systems with little endian. */
+ int tmp_fd;
+
type = zend_hash_get_current_key_ex(Z_ARRVAL_P(stream_array),
&key, &key_len, &num_ind, 0, NULL);
@@ -672,7 +682,10 @@ static int stream_array_from_fd_set(zval *stream_array, fd_set *fds TSRMLS_DC)
* when casting. It is only used here so that the buffered data warning
* is not displayed.
*/
- if (SUCCESS == php_stream_cast(stream, PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL, (void*)&this_fd, 1) && this_fd != -1) {
+ if (SUCCESS == php_stream_cast(stream, PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL, (void*)&tmp_fd, 1) && tmp_fd != -1) {
+
+ php_socket_t this_fd = (php_socket_t)tmp_fd;
+
if (PHP_SAFE_FD_ISSET(this_fd, fds)) {
if (type == HASH_KEY_IS_LONG) {
zend_hash_index_update(new_hash, num_ind, (void *)elem, sizeof(zval *), (void **)&dest_elem);
diff --git a/ext/standard/tests/file/bug24482.phpt b/ext/standard/tests/file/bug24482.phpt
index f545f1add..9d0568af3 100644
--- a/ext/standard/tests/file/bug24482.phpt
+++ b/ext/standard/tests/file/bug24482.phpt
@@ -8,6 +8,11 @@ if (!function_exists("glob")) {
?>
--FILE--
<?php
+
+// run this test in ext/standard/tests (see bug #64714)
+chdir(__DIR__); // ensure in ext/standard/tests/file
+chdir('..'); // move up to ext/standard/tests
+
$globdirs = glob("*", GLOB_ONLYDIR);
$dirs = array();
diff --git a/ext/standard/tests/streams/bug64770.phpt b/ext/standard/tests/streams/bug64770.phpt
new file mode 100644
index 000000000..785c4237a
--- /dev/null
+++ b/ext/standard/tests/streams/bug64770.phpt
@@ -0,0 +1,52 @@
+--TEST--
+Bug #64770 stream_select() fails with pipes from proc_open()
+--FILE--
+<?php
+
+$descs = array(
+ 0 => array('pipe', 'r'), // stdin
+ 1 => array('pipe', 'w'), // stdout
+ 2 => array('pipe', 'w'), // strerr
+);
+
+$other_opts = array('suppress_errors' => false, 'binary_pipes' => true);
+
+$cmd = (substr(PHP_OS, 0, 3) == 'WIN') ? 'dir' : 'ls';
+$p = proc_open($cmd, $descs, $pipes, '.', NULL, $other_opts);
+
+if (is_resource($p)) {
+ $data = '';
+
+ while (1) {
+ $w = $e = NULL;
+ $n = stream_select($pipes, $w, $e, 300);
+
+ if ($n === false) {
+ echo "no streams \n";
+ break;
+ } else if ($n === 0) {
+ echo "process timed out\n";
+ proc_terminate($p, 9);
+ break;
+ } else if ($n > 0) {
+ $line = fread($pipes[1], 8192);
+ if (strlen($line) == 0) {
+ /* EOF */
+ break;
+ }
+ $data .= $line;
+ }
+ }
+ var_dump(strlen($data));
+
+ $ret = proc_close($p);
+ var_dump($ret);
+} else {
+ echo "no process\n";
+}
+?>
+==DONE==
+--EXPECTF--
+int(%d)
+int(0)
+==DONE==