--- embedaddon/php/ext/standard/streamsfuncs.c 2012/02/21 23:48:02 1.1.1.1 +++ 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.1 2012/02/21 23:48:02 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)) { @@ -106,10 +106,6 @@ PHP_FUNCTION(stream_socket_client) context = php_stream_context_from_zval(zcontext, flags & PHP_FILE_NO_DEFAULT_CONTEXT); - if (context) { - zend_list_addref(context->rsrc_id); - } - if (flags & PHP_STREAM_CLIENT_PERSISTENT) { spprintf(&hashkey, 0, "stream_socket_client__%s", host); } @@ -132,7 +128,7 @@ PHP_FUNCTION(stream_socket_client) ZVAL_STRING(zerrstr, "", 1); } - stream = php_stream_xport_create(host, host_len, ENFORCE_SAFE_MODE | REPORT_ERRORS, + stream = php_stream_xport_create(host, host_len, REPORT_ERRORS, STREAM_XPORT_CLIENT | (flags & PHP_STREAM_CLIENT_CONNECT ? STREAM_XPORT_CONNECT : 0) | (flags & PHP_STREAM_CLIENT_ASYNC_CONNECT ? STREAM_XPORT_CONNECT_ASYNC : 0), hashkey, &tv, context, &errstr, &err); @@ -208,7 +204,7 @@ PHP_FUNCTION(stream_socket_server) ZVAL_STRING(zerrstr, "", 1); } - stream = php_stream_xport_create(host, host_len, ENFORCE_SAFE_MODE | REPORT_ERRORS, + stream = php_stream_xport_create(host, host_len, REPORT_ERRORS, STREAM_XPORT_SERVER | flags, NULL, NULL, context, &errstr, &err); @@ -395,13 +391,7 @@ PHP_FUNCTION(stream_socket_recvfrom) } read_buf[recvd] = '\0'; - if (PG(magic_quotes_runtime)) { - Z_TYPE_P(return_value) = IS_STRING; - Z_STRVAL_P(return_value) = php_addslashes(Z_STRVAL_P(return_value), Z_STRLEN_P(return_value), &Z_STRLEN_P(return_value), 1 TSRMLS_CC); - return; - } else { - RETURN_STRINGL(read_buf, recvd, 0); - } + RETURN_STRINGL(read_buf, recvd, 0); } efree(read_buf); @@ -417,8 +407,7 @@ PHP_FUNCTION(stream_get_contents) zval *zsrc; long maxlen = PHP_STREAM_COPY_ALL, desiredpos = -1L; - int len, - newlen; + int len; char *contents = NULL; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|ll", &zsrc, &maxlen, &desiredpos) == FAILURE) { @@ -450,10 +439,6 @@ PHP_FUNCTION(stream_get_contents) len = php_stream_copy_to_mem(stream, &contents, maxlen, 0); if (contents) { - if (len && PG(magic_quotes_runtime)) { - contents = php_addslashes(contents, len, &newlen, 1 TSRMLS_CC); /* 1 = free source string */ - len = newlen; - } RETVAL_STRINGL(contents, len, 0); } else { RETVAL_EMPTY_STRING(); @@ -557,7 +542,7 @@ PHP_FUNCTION(stream_get_transports) { HashTable *stream_xport_hash; char *stream_xport; - int stream_xport_len; + uint stream_xport_len; ulong num_key; if (zend_parse_parameters_none() == FAILURE) { @@ -586,7 +571,8 @@ PHP_FUNCTION(stream_get_wrappers) { HashTable *url_stream_wrappers_hash; char *stream_protocol; - int key_flags, stream_protocol_len = 0; + int key_flags; + uint stream_protocol_len = 0; ulong num_key; if (zend_parse_parameters_none() == FAILURE) { @@ -615,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) { @@ -625,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; @@ -634,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) { @@ -652,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) { @@ -662,9 +653,26 @@ static int stream_array_from_fd_set(zval *stream_array 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; + /* 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 || + 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; @@ -674,9 +682,17 @@ 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)) { - 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); } @@ -907,7 +923,7 @@ static int parse_context_options(php_stream_context *c HashPosition pos, opos; zval **wval, **oval; char *wkey, *okey; - int wkey_len, okey_len; + uint wkey_len, okey_len; int ret = SUCCESS; ulong num_key; @@ -970,7 +986,7 @@ static php_stream_context *decode_context_param(zval * { php_stream_context *context = NULL; - context = zend_fetch_resource(&contextresource TSRMLS_CC, -1, NULL, NULL, 1, php_le_stream_context()); + context = zend_fetch_resource(&contextresource TSRMLS_CC, -1, NULL, NULL, 1, php_le_stream_context(TSRMLS_C)); if (context == NULL) { php_stream *stream; @@ -983,7 +999,7 @@ static php_stream_context *decode_context_param(zval * param, but then something is called which requires a context. Don't give them the default one though since they already said they didn't want it. */ - context = stream->context = php_stream_context_alloc(); + context = stream->context = php_stream_context_alloc(TSRMLS_C); } } } @@ -1109,7 +1125,7 @@ PHP_FUNCTION(stream_context_get_default) } if (FG(default_context) == NULL) { - FG(default_context) = php_stream_context_alloc(); + FG(default_context) = php_stream_context_alloc(TSRMLS_C); } context = FG(default_context); @@ -1133,7 +1149,7 @@ PHP_FUNCTION(stream_context_set_default) } if (FG(default_context) == NULL) { - FG(default_context) = php_stream_context_alloc(); + FG(default_context) = php_stream_context_alloc(TSRMLS_C); } context = FG(default_context); @@ -1154,7 +1170,7 @@ PHP_FUNCTION(stream_context_create) RETURN_FALSE; } - context = php_stream_context_alloc(); + context = php_stream_context_alloc(TSRMLS_C); if (options) { parse_context_options(context, options TSRMLS_CC); @@ -1416,6 +1432,40 @@ PHP_FUNCTION(stream_set_write_buffer) } /* }}} */ +/* {{{ proto int stream_set_chunk_size(resource fp, int chunk_size) + Set the stream chunk size */ +PHP_FUNCTION(stream_set_chunk_size) +{ + int ret; + long csize; + zval *zstream; + php_stream *stream; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &zstream, &csize) == FAILURE) { + RETURN_FALSE; + } + + if (csize <= 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "The chunk size must be a positive integer, given %ld", csize); + RETURN_FALSE; + } + /* stream.chunk_size is actually a size_t, but php_stream_set_option + * can only use an int to accept the new value and return the old one. + * In any case, values larger than INT_MAX for a chunk size make no sense. + */ + if (csize > INT_MAX) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "The chunk size cannot be larger than %d", INT_MAX); + RETURN_FALSE; + } + + php_stream_from_zval(stream, &zstream); + + ret = php_stream_set_option(stream, PHP_STREAM_OPTION_SET_CHUNK_SIZE, (int)csize, NULL); + + RETURN_LONG(ret > 0 ? (long)ret : (long)EOF); +} +/* }}} */ + /* {{{ proto int stream_set_read_buffer(resource fp, int buffer) Set file read buffer */ PHP_FUNCTION(stream_set_read_buffer) @@ -1541,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;