Skip to content

Commit

Permalink
better fix for bug #64770
Browse files Browse the repository at this point in the history
  • Loading branch information
weltling committed May 4, 2013
1 parent f1269d8 commit 5c701d1
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 5 deletions.
21 changes: 17 additions & 4 deletions ext/standard/streamsfuncs.c
Expand Up @@ -611,7 +611,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 = 0;
int cnt = 0;

if (Z_TYPE_P(stream_array) != IS_ARRAY) {
Expand All @@ -621,6 +620,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;
Expand All @@ -630,7 +634,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);

Expand All @@ -648,7 +654,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 = 0;
int ret = 0;

if (Z_TYPE_P(stream_array) != IS_ARRAY) {
Expand All @@ -661,6 +666,11 @@ static int stream_array_from_fd_set(zval *stream_array, fd_set *fds TSRMLS_DC)
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;
Expand All @@ -670,7 +680,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)) {
zend_hash_next_index_insert(new_hash, (void *)elem, sizeof(zval *), (void **)&dest_elem);
if (dest_elem) {
Expand Down
3 changes: 2 additions & 1 deletion ext/standard/tests/streams/bug64770.phpt
Expand Up @@ -11,7 +11,8 @@ $descs = array(

$other_opts = array('suppress_errors' => false, 'binary_pipes' => true);

$p = proc_open('dir', $descs, $pipes, '.', NULL, $other_opts);
$cmd = (substr(PHP_OS, 0, 3) == 'WIN') ? 'dir' : 'ls';
$p = proc_open($cmd, $descs, $pipes, '.', NULL, $other_opts);

if (is_resource($p)) {
$data = '';
Expand Down

0 comments on commit 5c701d1

Please sign in to comment.