--- embedaddon/php/ext/standard/streamsfuncs.c 2012/05/29 12:34:43 1.1.1.2 +++ embedaddon/php/ext/standard/streamsfuncs.c 2013/07/22 01:32:05 1.1.1.3 @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2012 The PHP Group | + | Copyright (c) 1997-2013 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: streamsfuncs.c,v 1.1.1.2 2012/05/29 12:34:43 misho Exp $ */ +/* $Id: streamsfuncs.c,v 1.1.1.3 2013/07/22 01:32:05 misho Exp $ */ #include "php.h" #include "php_globals.h" @@ -51,7 +51,7 @@ PHP_FUNCTION(stream_socket_pair) { long domain, type, protocol; php_stream *s1, *s2; - int pair[2]; + php_socket_t pair[2]; if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lll", &domain, &type, &protocol)) { @@ -601,7 +601,6 @@ static int stream_array_to_fd_set(zval *stream_array, { 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, 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,8 +624,10 @@ static int stream_array_to_fd_set(zval *stream_array, * 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); if (this_fd > *max_fd) { @@ -638,7 +644,6 @@ static int stream_array_from_fd_set(zval *stream_array 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,7 +660,12 @@ static int stream_array_from_fd_set(zval *stream_array 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); if (type == HASH_KEY_NON_EXISTANT || @@ -672,7 +682,10 @@ static int stream_array_from_fd_set(zval *stream_array * 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); @@ -1578,7 +1591,7 @@ PHP_FUNCTION(stream_is_local) /* }}} */ /* {{{ proto bool stream_supports_lock(resource stream) - Tells wether the stream supports locking through flock(). */ + Tells whether the stream supports locking through flock(). */ PHP_FUNCTION(stream_supports_lock) { php_stream *stream;