diff options
Diffstat (limited to 'ext/standard/file.c')
-rw-r--r-- | ext/standard/file.c | 544 |
1 files changed, 291 insertions, 253 deletions
diff --git a/ext/standard/file.c b/ext/standard/file.c index 1ec6a74f3f..446da20fb3 100644 --- a/ext/standard/file.c +++ b/ext/standard/file.c @@ -1,8 +1,8 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2013 The PHP Group | + | Copyright (c) 1997-2014 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 | @@ -35,7 +35,7 @@ #include "php_open_temporary_file.h" #include "ext/standard/basic_functions.h" #include "php_ini.h" -#include "php_smart_str.h" +#include "zend_smart_str.h" #include <stdio.h> #include <stdlib.h> @@ -148,10 +148,10 @@ PHPAPI int php_le_stream_context(TSRMLS_D) */ static ZEND_RSRC_DTOR_FUNC(file_context_dtor) { - php_stream_context *context = (php_stream_context*)rsrc->ptr; - if (context->options) { + php_stream_context *context = (php_stream_context*)res->ptr; + if (Z_TYPE(context->options) != IS_UNDEF) { zval_ptr_dtor(&context->options); - context->options = NULL; + ZVAL_UNDEF(&context->options); } php_stream_context_free(context); } @@ -219,14 +219,22 @@ PHP_MINIT_FUNCTION(file) REGISTER_LONG_CONSTANT("STREAM_CLIENT_ASYNC_CONNECT", PHP_STREAM_CLIENT_ASYNC_CONNECT, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("STREAM_CLIENT_CONNECT", PHP_STREAM_CLIENT_CONNECT, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_SSLv2_CLIENT", STREAM_CRYPTO_METHOD_SSLv2_CLIENT, CONST_CS|CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_SSLv3_CLIENT", STREAM_CRYPTO_METHOD_SSLv3_CLIENT, CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_ANY_CLIENT", STREAM_CRYPTO_METHOD_ANY_CLIENT, CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_SSLv2_CLIENT", STREAM_CRYPTO_METHOD_SSLv2_CLIENT, CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_SSLv3_CLIENT", STREAM_CRYPTO_METHOD_SSLv3_CLIENT, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_SSLv23_CLIENT", STREAM_CRYPTO_METHOD_SSLv23_CLIENT, CONST_CS|CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_TLS_CLIENT", STREAM_CRYPTO_METHOD_TLS_CLIENT, CONST_CS|CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_SSLv2_SERVER", STREAM_CRYPTO_METHOD_SSLv2_SERVER, CONST_CS|CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_SSLv3_SERVER", STREAM_CRYPTO_METHOD_SSLv3_SERVER, CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_TLS_CLIENT", STREAM_CRYPTO_METHOD_TLS_CLIENT, CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT", STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT, CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT", STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT, CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT", STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT, CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_ANY_SERVER", STREAM_CRYPTO_METHOD_ANY_SERVER, CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_SSLv2_SERVER", STREAM_CRYPTO_METHOD_SSLv2_SERVER, CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_SSLv3_SERVER", STREAM_CRYPTO_METHOD_SSLv3_SERVER, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_SSLv23_SERVER", STREAM_CRYPTO_METHOD_SSLv23_SERVER, CONST_CS|CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_TLS_SERVER", STREAM_CRYPTO_METHOD_TLS_SERVER, CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_TLS_SERVER", STREAM_CRYPTO_METHOD_TLS_SERVER, CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_TLSv1_0_SERVER", STREAM_CRYPTO_METHOD_TLSv1_0_SERVER, CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_TLSv1_1_SERVER", STREAM_CRYPTO_METHOD_TLSv1_1_SERVER, CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_TLSv1_2_SERVER", STREAM_CRYPTO_METHOD_TLSv1_2_SERVER, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("STREAM_SHUT_RD", STREAM_SHUT_RD, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("STREAM_SHUT_WR", STREAM_SHUT_WR, CONST_CS|CONST_PERSISTENT); @@ -334,13 +342,13 @@ PHP_FUNCTION(flock) zval *arg1, *arg3 = NULL; int act; php_stream *stream; - long operation = 0; + zend_long operation = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|z", &arg1, &operation, &arg3) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|z/", &arg1, &operation, &arg3) == FAILURE) { return; } - PHP_STREAM_TO_ZVAL(stream, &arg1); + PHP_STREAM_TO_ZVAL(stream, arg1); act = operation & 3; if (act < 1 || act > 3) { @@ -348,16 +356,16 @@ PHP_FUNCTION(flock) RETURN_FALSE; } - if (arg3 && PZVAL_IS_REF(arg3)) { - convert_to_long_ex(&arg3); - Z_LVAL_P(arg3) = 0; + if (arg3) { + zval_dtor(arg3); + ZVAL_LONG(arg3, 0); } /* flock_values contains all possible actions if (operation & 4) we won't block on the lock */ act = flock_values[act - 1] | (operation & PHP_LOCK_NB ? LOCK_NB : 0); if (php_stream_lock(stream, act)) { - if (operation && errno == EWOULDBLOCK && arg3 && PZVAL_IS_REF(arg3)) { - Z_LVAL_P(arg3) = 1; + if (operation && errno == EWOULDBLOCK && arg3) { + ZVAL_LONG(arg3, 1); } RETURN_FALSE; } @@ -372,7 +380,7 @@ PHP_FUNCTION(flock) PHP_FUNCTION(get_meta_tags) { char *filename; - int filename_len; + size_t filename_len; zend_bool use_include_path = 0; int in_tag = 0, done = 0; int looking_for_val = 0, have_name = 0, have_content = 0; @@ -411,7 +419,7 @@ PHP_FUNCTION(get_meta_tags) } } else if (tok_last == TOK_EQUAL && looking_for_val) { if (saw_name) { - STR_FREE(name); + if (name) efree(name); /* Get the NAME attr (Single word attr, non-quoted) */ temp = name = estrndup(md.token_data, md.token_len); @@ -424,7 +432,7 @@ PHP_FUNCTION(get_meta_tags) have_name = 1; } else if (saw_content) { - STR_FREE(value); + if (value) efree(value); value = estrndup(md.token_data, md.token_len); have_content = 1; } @@ -445,7 +453,7 @@ PHP_FUNCTION(get_meta_tags) } } else if (tok == TOK_STRING && tok_last == TOK_EQUAL && looking_for_val) { if (saw_name) { - STR_FREE(name); + if (name) efree(name); /* Get the NAME attr (Quoted single/double) */ temp = name = estrndup(md.token_data, md.token_len); @@ -458,7 +466,7 @@ PHP_FUNCTION(get_meta_tags) have_name = 1; } else if (saw_content) { - STR_FREE(value); + if (value) efree(value); value = estrndup(md.token_data, md.token_len); have_content = 1; } @@ -476,13 +484,13 @@ PHP_FUNCTION(get_meta_tags) /* For BC */ php_strtolower(name, strlen(name)); if (have_content) { - add_assoc_string(return_value, name, value, 1); + add_assoc_string(return_value, name, value); } else { - add_assoc_string(return_value, name, "", 1); + add_assoc_string(return_value, name, ""); } efree(name); - STR_FREE(value); + if (value) efree(value); } else if (have_content) { efree(value); } @@ -504,8 +512,8 @@ PHP_FUNCTION(get_meta_tags) md.token_data = NULL; } - STR_FREE(value); - STR_FREE(name); + if (value) efree(value); + if (name) efree(name); php_stream_close(md.stream); } /* }}} */ @@ -515,15 +523,14 @@ PHP_FUNCTION(get_meta_tags) PHP_FUNCTION(file_get_contents) { char *filename; - int filename_len; - char *contents; + size_t filename_len; zend_bool use_include_path = 0; php_stream *stream; - int len; - long offset = -1; - long maxlen = PHP_STREAM_COPY_ALL; + zend_long offset = -1; + zend_long maxlen = PHP_STREAM_COPY_ALL; zval *zcontext = NULL; php_stream_context *context = NULL; + zend_string *contents; /* Parse arguments */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|br!ll", &filename, &filename_len, &use_include_path, &zcontext, &offset, &maxlen) == FAILURE) { @@ -545,17 +552,19 @@ PHP_FUNCTION(file_get_contents) } if (offset > 0 && php_stream_seek(stream, offset, SEEK_SET) < 0) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to seek to position %ld in the stream", offset); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to seek to position " ZEND_LONG_FMT " in the stream", offset); php_stream_close(stream); RETURN_FALSE; } - if ((len = php_stream_copy_to_mem(stream, &contents, maxlen, 0)) > 0) { - RETVAL_STRINGL(contents, len, 0); - } else if (len == 0) { - RETVAL_EMPTY_STRING(); + if (maxlen > INT_MAX) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "maxlen truncated from %pd to %d bytes", maxlen, INT_MAX); + maxlen = INT_MAX; + } + if ((contents = php_stream_copy_to_mem(stream, maxlen, 0)) != NULL) { + RETVAL_STR(contents); } else { - RETVAL_FALSE; + RETVAL_EMPTY_STRING(); } php_stream_close(stream); @@ -568,21 +577,22 @@ PHP_FUNCTION(file_put_contents) { php_stream *stream; char *filename; - int filename_len; + size_t filename_len; zval *data; - int numbytes = 0; - long flags = 0; + zend_long numbytes = 0; + zend_long flags = 0; zval *zcontext = NULL; php_stream_context *context = NULL; php_stream *srcstream = NULL; char mode[3] = "wb"; + char ret_ok = 1; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "pz/|lr!", &filename, &filename_len, &data, &flags, &zcontext) == FAILURE) { return; } if (Z_TYPE_P(data) == IS_RESOURCE) { - php_stream_from_zval(srcstream, &data); + php_stream_from_zval(srcstream, data); } context = php_stream_context_from_zval(zcontext, flags & PHP_FILE_NO_DEFAULT_CONTEXT); @@ -620,8 +630,12 @@ PHP_FUNCTION(file_put_contents) case IS_RESOURCE: { size_t len; if (php_stream_copy_to_stream_ex(srcstream, stream, PHP_STREAM_COPY_ALL, &len) != SUCCESS) { - numbytes = -1; + ret_ok = 0; } else { + if (len > ZEND_LONG_MAX) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "content truncated from %zu to " ZEND_LONG_FMT " bytes", len, ZEND_LONG_MAX); + len = ZEND_LONG_MAX; + } numbytes = len; } break; @@ -629,15 +643,15 @@ PHP_FUNCTION(file_put_contents) case IS_NULL: case IS_LONG: case IS_DOUBLE: - case IS_BOOL: - case IS_CONSTANT: - convert_to_string_ex(&data); + case IS_FALSE: + case IS_TRUE: + convert_to_string_ex(data); case IS_STRING: if (Z_STRLEN_P(data)) { numbytes = php_stream_write(stream, Z_STRVAL_P(data), Z_STRLEN_P(data)); if (numbytes != Z_STRLEN_P(data)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Only %d of %d bytes written, possibly out of free disk space", numbytes, Z_STRLEN_P(data)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Only %pl of %zd bytes written, possibly out of free disk space", numbytes, Z_STRLEN_P(data)); numbytes = -1; } } @@ -645,31 +659,23 @@ PHP_FUNCTION(file_put_contents) case IS_ARRAY: if (zend_hash_num_elements(Z_ARRVAL_P(data))) { - int bytes_written; - zval **tmp; - HashPosition pos; - - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(data), &pos); - while (zend_hash_get_current_data_ex(Z_ARRVAL_P(data), (void **) &tmp, &pos) == SUCCESS) { - if (Z_TYPE_PP(tmp) != IS_STRING) { - SEPARATE_ZVAL(tmp); - convert_to_string(*tmp); - } - if (Z_STRLEN_PP(tmp)) { - numbytes += Z_STRLEN_PP(tmp); - bytes_written = php_stream_write(stream, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp)); - if (bytes_written < 0 || bytes_written != Z_STRLEN_PP(tmp)) { - if (bytes_written < 0) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to write %d bytes to %s", Z_STRLEN_PP(tmp), filename); - } else { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Only %d of %d bytes written, possibly out of free disk space", bytes_written, Z_STRLEN_PP(tmp)); - } - numbytes = -1; + size_t bytes_written; + zval *tmp; + + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(data), tmp) { + zend_string *str = zval_get_string(tmp); + if (str->len) { + numbytes += str->len; + bytes_written = php_stream_write(stream, str->val, str->len); + if (bytes_written != str->len) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to write %zd bytes to %s", str->len, filename); + ret_ok = 0; + zend_string_release(str); break; } } - zend_hash_move_forward_ex(Z_ARRVAL_P(data), &pos); - } + zend_string_release(str); + } ZEND_HASH_FOREACH_END(); } break; @@ -680,7 +686,7 @@ PHP_FUNCTION(file_put_contents) if (zend_std_cast_object_tostring(data, &out, IS_STRING TSRMLS_CC) == SUCCESS) { numbytes = php_stream_write(stream, Z_STRVAL(out), Z_STRLEN(out)); if (numbytes != Z_STRLEN(out)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Only %d of %d bytes written, possibly out of free disk space", numbytes, Z_STRLEN(out)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Only %pd of %zd bytes written, possibly out of free disk space", numbytes, Z_STRLEN(out)); numbytes = -1; } zval_dtor(&out); @@ -688,12 +694,12 @@ PHP_FUNCTION(file_put_contents) } } default: - numbytes = -1; + ret_ok = 0; break; } php_stream_close(stream); - if (numbytes < 0) { + if (!ret_ok) { RETURN_FALSE; } @@ -708,25 +714,25 @@ PHP_FUNCTION(file_put_contents) PHP_FUNCTION(file) { char *filename; - int filename_len; - char *target_buf=NULL, *p, *s, *e; + size_t filename_len; + char *p, *s, *e; register int i = 0; - int target_len; char eol_marker = '\n'; - long flags = 0; + zend_long flags = 0; zend_bool use_include_path; zend_bool include_new_line; zend_bool skip_blank_lines; php_stream *stream; zval *zcontext = NULL; php_stream_context *context = NULL; + zend_string *target_buf; /* Parse arguments */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|lr!", &filename, &filename_len, &flags, &zcontext) == FAILURE) { return; } if (flags < 0 || flags > (PHP_FILE_USE_INCLUDE_PATH | PHP_FILE_IGNORE_NEW_LINES | PHP_FILE_SKIP_EMPTY_LINES | PHP_FILE_NO_DEFAULT_CONTEXT)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "'%ld' flag is not supported", flags); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "'" ZEND_LONG_FMT "' flag is not supported", flags); RETURN_FALSE; } @@ -744,11 +750,11 @@ PHP_FUNCTION(file) /* Initialize return array */ array_init(return_value); - if ((target_len = php_stream_copy_to_mem(stream, &target_buf, PHP_STREAM_COPY_ALL, 0))) { - s = target_buf; - e = target_buf + target_len; + if ((target_buf = php_stream_copy_to_mem(stream, PHP_STREAM_COPY_ALL, 0)) != NULL) { + s = target_buf->val; + e = target_buf->val + target_buf->len; - if (!(p = php_stream_locate_eol(stream, target_buf, target_len TSRMLS_CC))) { + if (!(p = (char*)php_stream_locate_eol(stream, target_buf TSRMLS_CC))) { p = e; goto parse_eol; } @@ -763,20 +769,20 @@ PHP_FUNCTION(file) do { p++; parse_eol: - add_index_stringl(return_value, i++, estrndup(s, p-s), p-s, 0); + add_index_stringl(return_value, i++, s, p-s); s = p; } while ((p = memchr(p, eol_marker, (e-p)))); } else { do { int windows_eol = 0; - if (p != target_buf && eol_marker == '\n' && *(p - 1) == '\r') { + if (p != target_buf->val && eol_marker == '\n' && *(p - 1) == '\r') { windows_eol++; } if (skip_blank_lines && !(p-s-windows_eol)) { s = ++p; continue; } - add_index_stringl(return_value, i++, estrndup(s, p-s-windows_eol), p-s-windows_eol, 0); + add_index_stringl(return_value, i++, s, p-s-windows_eol); s = ++p; } while ((p = memchr(p, eol_marker, (e-p)))); } @@ -789,7 +795,7 @@ parse_eol: } if (target_buf) { - efree(target_buf); + zend_string_free(target_buf); } php_stream_close(stream); } @@ -800,11 +806,10 @@ parse_eol: PHP_FUNCTION(tempnam) { char *dir, *prefix; - int dir_len, prefix_len; - size_t p_len; + size_t dir_len, prefix_len; char *opened_path; - char *p; int fd; + zend_string *p; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ps", &dir, &dir_len, &prefix, &prefix_len) == FAILURE) { return; @@ -814,18 +819,20 @@ PHP_FUNCTION(tempnam) RETURN_FALSE; } - php_basename(prefix, prefix_len, NULL, 0, &p, &p_len TSRMLS_CC); - if (p_len > 64) { - p[63] = '\0'; + p = php_basename(prefix, prefix_len, NULL, 0 TSRMLS_CC); + if (p->len > 64) { + p->val[63] = '\0'; } RETVAL_FALSE; - if ((fd = php_open_temporary_fd_ex(dir, p, &opened_path, 1 TSRMLS_CC)) >= 0) { + if ((fd = php_open_temporary_fd_ex(dir, p->val, &opened_path, 1 TSRMLS_CC)) >= 0) { close(fd); - RETVAL_STRING(opened_path, 0); + // TODO: avoid reallocation ??? + RETVAL_STRING(opened_path); + efree(opened_path); } - efree(p); + zend_string_release(p); } /* }}} */ @@ -854,7 +861,7 @@ PHP_NAMED_FUNCTION(php_if_tmpfile) PHP_NAMED_FUNCTION(php_if_fopen) { char *filename, *mode; - int filename_len, mode_len; + size_t filename_len, mode_len; zend_bool use_include_path = 0; zval *zcontext = NULL; php_stream *stream; @@ -883,14 +890,20 @@ PHPAPI PHP_FUNCTION(fclose) zval *arg1; php_stream *stream; +#ifndef FAST_ZPP if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) == FAILURE) { RETURN_FALSE; } +#else + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_RESOURCE(arg1) + ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); +#endif - PHP_STREAM_TO_ZVAL(stream, &arg1); + PHP_STREAM_TO_ZVAL(stream, arg1); if ((stream->flags & PHP_STREAM_FLAG_NO_FCLOSE) != 0) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "%d is not a valid stream resource", stream->rsrc_id); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "%pd is not a valid stream resource", stream->res->handle); RETURN_FALSE; } @@ -909,7 +922,7 @@ PHPAPI PHP_FUNCTION(fclose) PHP_FUNCTION(popen) { char *command, *mode; - int command_len, mode_len; + size_t command_len, mode_len; FILE *fp; php_stream *stream; char *posix_mode; @@ -959,10 +972,10 @@ PHP_FUNCTION(pclose) RETURN_FALSE; } - PHP_STREAM_TO_ZVAL(stream, &arg1); + PHP_STREAM_TO_ZVAL(stream, arg1); FG(pclose_wait) = 1; - zend_list_delete(stream->rsrc_id); + zend_list_close(stream->res); FG(pclose_wait) = 0; RETURN_LONG(FG(pclose_ret)); } @@ -979,7 +992,7 @@ PHPAPI PHP_FUNCTION(feof) RETURN_FALSE; } - PHP_STREAM_TO_ZVAL(stream, &arg1); + PHP_STREAM_TO_ZVAL(stream, arg1); if (php_stream_eof(stream)) { RETURN_TRUE; @@ -994,7 +1007,7 @@ PHPAPI PHP_FUNCTION(feof) PHPAPI PHP_FUNCTION(fgets) { zval *arg1; - long len = 1024; + zend_long len = 1024; char *buf = NULL; int argc = ZEND_NUM_ARGS(); size_t line_len = 0; @@ -1004,7 +1017,7 @@ PHPAPI PHP_FUNCTION(fgets) RETURN_FALSE; } - PHP_STREAM_TO_ZVAL(stream, &arg1); + PHP_STREAM_TO_ZVAL(stream, arg1); if (argc == 1) { /* ask streams to give us a buffer of an appropriate size */ @@ -1024,12 +1037,17 @@ PHPAPI PHP_FUNCTION(fgets) } } - ZVAL_STRINGL(return_value, buf, line_len, 0); /* resize buffer if it's much larger than the result. * Only needed if the user requested a buffer size. */ - if (argc > 1 && Z_STRLEN_P(return_value) < len / 2) { - Z_STRVAL_P(return_value) = erealloc(buf, line_len + 1); - } +//?? if (argc > 1 && line_len < len / 2) { +//??? + ZVAL_STRINGL(return_value, buf, line_len); + efree(buf); +//?? } else { +//??? +//??? ZVAL_STRINGL(return_value, buf, line_len); +//??? efree(buf); +//??? } return; exit_failed: @@ -1053,7 +1071,7 @@ PHPAPI PHP_FUNCTION(fgetc) RETURN_FALSE; } - PHP_STREAM_TO_ZVAL(stream, &arg1); + PHP_STREAM_TO_ZVAL(stream, arg1); result = php_stream_getc(stream); @@ -1063,7 +1081,7 @@ PHPAPI PHP_FUNCTION(fgetc) buf[0] = result; buf[1] = '\0'; - RETURN_STRINGL(buf, 1, 1); + RETURN_STRINGL(buf, 1); } } /* }}} */ @@ -1073,19 +1091,20 @@ PHPAPI PHP_FUNCTION(fgetc) PHPAPI PHP_FUNCTION(fgetss) { zval *fd; - long bytes = 0; + zend_long bytes = 0; size_t len = 0; size_t actual_len, retval_len; char *buf = NULL, *retval; php_stream *stream; + zend_string *allowed = NULL; char *allowed_tags=NULL; int allowed_tags_len=0; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|ls", &fd, &bytes, &allowed_tags, &allowed_tags_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|lS", &fd, &bytes, &allowed) == FAILURE) { RETURN_FALSE; } - PHP_STREAM_TO_ZVAL(stream, &fd); + PHP_STREAM_TO_ZVAL(stream, fd); if (ZEND_NUM_ARGS() >= 2) { if (bytes <= 0) { @@ -1106,9 +1125,27 @@ PHPAPI PHP_FUNCTION(fgetss) RETURN_FALSE; } + if (allowed != NULL) { +// TODO: reimplement to avoid reallocation ??? + if (IS_INTERNED(allowed)) { + allowed_tags = estrndup(allowed->val, allowed->len); + allowed_tags_len = allowed->len; + } else { + allowed_tags = allowed->val; + allowed_tags_len = allowed->len; + } + } + retval_len = php_strip_tags(retval, actual_len, &stream->fgetss_state, allowed_tags, allowed_tags_len); - RETURN_STRINGL(retval, retval_len, 0); +// TODO: reimplement to avoid reallocation ??? + if (allowed && IS_INTERNED(allowed)) { + efree(allowed_tags); + } + + // TODO: avoid reallocation ??? + RETVAL_STRINGL(retval, retval_len); + efree(retval); } /* }}} */ @@ -1116,8 +1153,9 @@ PHPAPI PHP_FUNCTION(fgetss) Implements a mostly ANSI compatible fscanf() */ PHP_FUNCTION(fscanf) { - int result, format_len, type, argc = 0; - zval ***args = NULL; + int result, type, argc = 0; + size_t format_len; + zval *args = NULL; zval *file_handle; char *buf, *format; size_t len; @@ -1127,31 +1165,22 @@ PHP_FUNCTION(fscanf) return; } - what = zend_fetch_resource(&file_handle TSRMLS_CC, -1, "File-Handle", &type, 2, php_file_le_stream(), php_file_le_pstream()); + what = zend_fetch_resource(file_handle TSRMLS_CC, -1, "File-Handle", &type, 2, php_file_le_stream(), php_file_le_pstream()); /* we can't do a ZEND_VERIFY_RESOURCE(what), otherwise we end up * with a leak if we have an invalid filehandle. This needs changing * if the code behind ZEND_VERIFY_RESOURCE changed. - cc */ if (!what) { - if (args) { - efree(args); - } RETURN_FALSE; } buf = php_stream_get_line((php_stream *) what, NULL, 0, &len); if (buf == NULL) { - if (args) { - efree(args); - } RETURN_FALSE; } - result = php_sscanf_internal(buf, format, argc, args, 0, &return_value TSRMLS_CC); + result = php_sscanf_internal(buf, format, argc, args, 0, return_value TSRMLS_CC); - if (args) { - efree(args); - } efree(buf); if (SCAN_ERROR_WRONG_PARAM_COUNT == result) { @@ -1166,10 +1195,10 @@ PHPAPI PHP_FUNCTION(fwrite) { zval *arg1; char *arg2; - int arg2len; + size_t arg2len; int ret; int num_bytes; - long arg3 = 0; + zend_long arg3 = 0; char *buffer = NULL; php_stream *stream; @@ -1180,14 +1209,18 @@ PHPAPI PHP_FUNCTION(fwrite) if (ZEND_NUM_ARGS() == 2) { num_bytes = arg2len; } else { - num_bytes = MAX(0, MIN((int)arg3, arg2len)); + if (arg3 > 0) { + num_bytes = MIN((size_t)arg3, arg2len); + } else { + num_bytes = 0; + } } if (!num_bytes) { RETURN_LONG(0); } - PHP_STREAM_TO_ZVAL(stream, &arg1); + PHP_STREAM_TO_ZVAL(stream, arg1); ret = php_stream_write(stream, buffer ? buffer : arg2, num_bytes); if (buffer) { @@ -1210,7 +1243,7 @@ PHPAPI PHP_FUNCTION(fflush) RETURN_FALSE; } - PHP_STREAM_TO_ZVAL(stream, &arg1); + PHP_STREAM_TO_ZVAL(stream, arg1); ret = php_stream_flush(stream); if (ret) { @@ -1231,7 +1264,7 @@ PHPAPI PHP_FUNCTION(rewind) RETURN_FALSE; } - PHP_STREAM_TO_ZVAL(stream, &arg1); + PHP_STREAM_TO_ZVAL(stream, arg1); if (-1 == php_stream_rewind(stream)) { RETURN_FALSE; @@ -1245,14 +1278,14 @@ PHPAPI PHP_FUNCTION(rewind) PHPAPI PHP_FUNCTION(ftell) { zval *arg1; - long ret; + zend_long ret; php_stream *stream; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) == FAILURE) { RETURN_FALSE; } - PHP_STREAM_TO_ZVAL(stream, &arg1); + PHP_STREAM_TO_ZVAL(stream, arg1); ret = php_stream_tell(stream); if (ret == -1) { @@ -1267,14 +1300,14 @@ PHPAPI PHP_FUNCTION(ftell) PHPAPI PHP_FUNCTION(fseek) { zval *arg1; - long arg2, whence = SEEK_SET; + zend_long arg2, whence = SEEK_SET; php_stream *stream; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|l", &arg1, &arg2, &whence) == FAILURE) { RETURN_FALSE; } - PHP_STREAM_TO_ZVAL(stream, &arg1); + PHP_STREAM_TO_ZVAL(stream, arg1); RETURN_LONG(php_stream_seek(stream, arg2, whence)); } @@ -1284,7 +1317,7 @@ PHPAPI PHP_FUNCTION(fseek) */ /* DEPRECATED APIs: Use php_stream_mkdir() instead */ -PHPAPI int php_mkdir_ex(const char *dir, long mode, int options TSRMLS_DC) +PHPAPI int php_mkdir_ex(const char *dir, zend_long mode, int options TSRMLS_DC) { int ret; @@ -1299,7 +1332,7 @@ PHPAPI int php_mkdir_ex(const char *dir, long mode, int options TSRMLS_DC) return ret; } -PHPAPI int php_mkdir(const char *dir, long mode TSRMLS_DC) +PHPAPI int php_mkdir(const char *dir, zend_long mode TSRMLS_DC) { return php_mkdir_ex(dir, mode, REPORT_ERRORS TSRMLS_CC); } @@ -1310,9 +1343,9 @@ PHPAPI int php_mkdir(const char *dir, long mode TSRMLS_DC) PHP_FUNCTION(mkdir) { char *dir; - int dir_len; + size_t dir_len; zval *zcontext = NULL; - long mode = 0777; + zend_long mode = 0777; zend_bool recursive = 0; php_stream_context *context; @@ -1331,7 +1364,7 @@ PHP_FUNCTION(mkdir) PHP_FUNCTION(rmdir) { char *dir; - int dir_len; + size_t dir_len; zval *zcontext = NULL; php_stream_context *context; @@ -1350,7 +1383,7 @@ PHP_FUNCTION(rmdir) PHP_FUNCTION(readfile) { char *filename; - int filename_len; + size_t filename_len; int size = 0; zend_bool use_include_path = 0; zval *zcontext = NULL; @@ -1378,7 +1411,7 @@ PHP_FUNCTION(readfile) Return or change the umask */ PHP_FUNCTION(umask) { - long arg1 = 0; + zend_long arg1 = 0; int oldumask; oldumask = umask(077); @@ -1413,7 +1446,7 @@ PHPAPI PHP_FUNCTION(fpassthru) RETURN_FALSE; } - PHP_STREAM_TO_ZVAL(stream, &arg1); + PHP_STREAM_TO_ZVAL(stream, arg1); size = php_stream_passthru(stream); RETURN_LONG(size); @@ -1425,7 +1458,7 @@ PHPAPI PHP_FUNCTION(fpassthru) PHP_FUNCTION(rename) { char *old_name, *new_name; - int old_name_len, new_name_len; + size_t old_name_len, new_name_len; zval *zcontext = NULL; php_stream_wrapper *wrapper; php_stream_context *context; @@ -1462,7 +1495,7 @@ PHP_FUNCTION(rename) PHP_FUNCTION(unlink) { char *filename; - int filename_len; + size_t filename_len; php_stream_wrapper *wrapper; zval *zcontext = NULL; php_stream_context *context = NULL; @@ -1493,14 +1526,14 @@ PHP_FUNCTION(unlink) PHP_NAMED_FUNCTION(php_if_ftruncate) { zval *fp; - long size; + zend_long size; php_stream *stream; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &fp, &size) == FAILURE) { RETURN_FALSE; } - PHP_STREAM_TO_ZVAL(stream, &fp); + PHP_STREAM_TO_ZVAL(stream, fp); if (!php_stream_truncate_supported(stream)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't truncate this stream!"); @@ -1516,8 +1549,8 @@ PHP_NAMED_FUNCTION(php_if_ftruncate) PHP_NAMED_FUNCTION(php_if_fstat) { zval *fp; - zval *stat_dev, *stat_ino, *stat_mode, *stat_nlink, *stat_uid, *stat_gid, *stat_rdev, - *stat_size, *stat_atime, *stat_mtime, *stat_ctime, *stat_blksize, *stat_blocks; + zval stat_dev, stat_ino, stat_mode, stat_nlink, stat_uid, stat_gid, stat_rdev, + stat_size, stat_atime, stat_mtime, stat_ctime, stat_blksize, stat_blocks; php_stream *stream; php_stream_statbuf stat_ssb; char *stat_sb_names[13] = { @@ -1529,7 +1562,7 @@ PHP_NAMED_FUNCTION(php_if_fstat) RETURN_FALSE; } - PHP_STREAM_TO_ZVAL(stream, &fp); + PHP_STREAM_TO_ZVAL(stream, fp); if (php_stream_stat(stream, &stat_ssb)) { RETURN_FALSE; @@ -1537,60 +1570,72 @@ PHP_NAMED_FUNCTION(php_if_fstat) array_init(return_value); - MAKE_LONG_ZVAL_INCREF(stat_dev, stat_ssb.sb.st_dev); - MAKE_LONG_ZVAL_INCREF(stat_ino, stat_ssb.sb.st_ino); - MAKE_LONG_ZVAL_INCREF(stat_mode, stat_ssb.sb.st_mode); - MAKE_LONG_ZVAL_INCREF(stat_nlink, stat_ssb.sb.st_nlink); - MAKE_LONG_ZVAL_INCREF(stat_uid, stat_ssb.sb.st_uid); - MAKE_LONG_ZVAL_INCREF(stat_gid, stat_ssb.sb.st_gid); + ZVAL_LONG(&stat_dev, stat_ssb.sb.st_dev); + ZVAL_LONG(&stat_ino, stat_ssb.sb.st_ino); + ZVAL_LONG(&stat_mode, stat_ssb.sb.st_mode); + ZVAL_LONG(&stat_nlink, stat_ssb.sb.st_nlink); + ZVAL_LONG(&stat_uid, stat_ssb.sb.st_uid); + ZVAL_LONG(&stat_gid, stat_ssb.sb.st_gid); #ifdef HAVE_ST_RDEV - MAKE_LONG_ZVAL_INCREF(stat_rdev, stat_ssb.sb.st_rdev); +# ifdef PHP_WIN32 + /* It is unsigned, so if a negative came from userspace, it'll + convert to UINT_MAX, but we wan't to keep the userspace value. + Almost the same as in php_fstat. This is ugly, but otherwise + we would have to maintain a fully compatible struct stat. */ + if ((int)stat_ssb.sb.st_rdev < 0) { + ZVAL_LONG(&stat_rdev, (int)stat_ssb.sb.st_rdev); + } else { + ZVAL_LONG(&stat_rdev, stat_ssb.sb.st_rdev); + } +# else + ZVAL_LONG(&stat_rdev, stat_ssb.sb.st_rdev); +# endif #else - MAKE_LONG_ZVAL_INCREF(stat_rdev, -1); + ZVAL_LONG(&stat_rdev, -1); #endif - MAKE_LONG_ZVAL_INCREF(stat_size, stat_ssb.sb.st_size); - MAKE_LONG_ZVAL_INCREF(stat_atime, stat_ssb.sb.st_atime); - MAKE_LONG_ZVAL_INCREF(stat_mtime, stat_ssb.sb.st_mtime); - MAKE_LONG_ZVAL_INCREF(stat_ctime, stat_ssb.sb.st_ctime); + ZVAL_LONG(&stat_size, stat_ssb.sb.st_size); + ZVAL_LONG(&stat_atime, stat_ssb.sb.st_atime); + ZVAL_LONG(&stat_mtime, stat_ssb.sb.st_mtime); + ZVAL_LONG(&stat_ctime, stat_ssb.sb.st_ctime); #ifdef HAVE_ST_BLKSIZE - MAKE_LONG_ZVAL_INCREF(stat_blksize, stat_ssb.sb.st_blksize); + ZVAL_LONG(&stat_blksize, stat_ssb.sb.st_blksize); #else - MAKE_LONG_ZVAL_INCREF(stat_blksize,-1); + ZVAL_LONG(&stat_blksize,-1); #endif #ifdef HAVE_ST_BLOCKS - MAKE_LONG_ZVAL_INCREF(stat_blocks, stat_ssb.sb.st_blocks); + ZVAL_LONG(&stat_blocks, stat_ssb.sb.st_blocks); #else - MAKE_LONG_ZVAL_INCREF(stat_blocks,-1); + ZVAL_LONG(&stat_blocks,-1); #endif /* Store numeric indexes in propper order */ - zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_dev, sizeof(zval *), NULL); - zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_ino, sizeof(zval *), NULL); - zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_mode, sizeof(zval *), NULL); - zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_nlink, sizeof(zval *), NULL); - zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_uid, sizeof(zval *), NULL); - zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_gid, sizeof(zval *), NULL); - zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_rdev, sizeof(zval *), NULL); - zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_size, sizeof(zval *), NULL); - zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_atime, sizeof(zval *), NULL); - zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_mtime, sizeof(zval *), NULL); - zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_ctime, sizeof(zval *), NULL); - zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_blksize, sizeof(zval *), NULL); - zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_blocks, sizeof(zval *), NULL); + zend_hash_next_index_insert(HASH_OF(return_value), &stat_dev); + zend_hash_next_index_insert(HASH_OF(return_value), &stat_ino); + zend_hash_next_index_insert(HASH_OF(return_value), &stat_mode); + zend_hash_next_index_insert(HASH_OF(return_value), &stat_nlink); + zend_hash_next_index_insert(HASH_OF(return_value), &stat_uid); + zend_hash_next_index_insert(HASH_OF(return_value), &stat_gid); + zend_hash_next_index_insert(HASH_OF(return_value), &stat_rdev); + zend_hash_next_index_insert(HASH_OF(return_value), &stat_size); + zend_hash_next_index_insert(HASH_OF(return_value), &stat_atime); + zend_hash_next_index_insert(HASH_OF(return_value), &stat_mtime); + zend_hash_next_index_insert(HASH_OF(return_value), &stat_ctime); + zend_hash_next_index_insert(HASH_OF(return_value), &stat_blksize); + zend_hash_next_index_insert(HASH_OF(return_value), &stat_blocks); /* Store string indexes referencing the same zval*/ - zend_hash_update(HASH_OF(return_value), stat_sb_names[0], strlen(stat_sb_names[0])+1, (void *)&stat_dev, sizeof(zval *), NULL); - zend_hash_update(HASH_OF(return_value), stat_sb_names[1], strlen(stat_sb_names[1])+1, (void *)&stat_ino, sizeof(zval *), NULL); - zend_hash_update(HASH_OF(return_value), stat_sb_names[2], strlen(stat_sb_names[2])+1, (void *)&stat_mode, sizeof(zval *), NULL); - zend_hash_update(HASH_OF(return_value), stat_sb_names[3], strlen(stat_sb_names[3])+1, (void *)&stat_nlink, sizeof(zval *), NULL); - zend_hash_update(HASH_OF(return_value), stat_sb_names[4], strlen(stat_sb_names[4])+1, (void *)&stat_uid, sizeof(zval *), NULL); - zend_hash_update(HASH_OF(return_value), stat_sb_names[5], strlen(stat_sb_names[5])+1, (void *)&stat_gid, sizeof(zval *), NULL); - zend_hash_update(HASH_OF(return_value), stat_sb_names[6], strlen(stat_sb_names[6])+1, (void *)&stat_rdev, sizeof(zval *), NULL); - zend_hash_update(HASH_OF(return_value), stat_sb_names[7], strlen(stat_sb_names[7])+1, (void *)&stat_size, sizeof(zval *), NULL); - zend_hash_update(HASH_OF(return_value), stat_sb_names[8], strlen(stat_sb_names[8])+1, (void *)&stat_atime, sizeof(zval *), NULL); - zend_hash_update(HASH_OF(return_value), stat_sb_names[9], strlen(stat_sb_names[9])+1, (void *)&stat_mtime, sizeof(zval *), NULL); - zend_hash_update(HASH_OF(return_value), stat_sb_names[10], strlen(stat_sb_names[10])+1, (void *)&stat_ctime, sizeof(zval *), NULL); - zend_hash_update(HASH_OF(return_value), stat_sb_names[11], strlen(stat_sb_names[11])+1, (void *)&stat_blksize, sizeof(zval *), NULL); - zend_hash_update(HASH_OF(return_value), stat_sb_names[12], strlen(stat_sb_names[12])+1, (void *)&stat_blocks, sizeof(zval *), NULL); + zend_hash_str_update(HASH_OF(return_value), stat_sb_names[0], strlen(stat_sb_names[0]), &stat_dev); + zend_hash_str_update(HASH_OF(return_value), stat_sb_names[1], strlen(stat_sb_names[1]), &stat_ino); + zend_hash_str_update(HASH_OF(return_value), stat_sb_names[2], strlen(stat_sb_names[2]), &stat_mode); + zend_hash_str_update(HASH_OF(return_value), stat_sb_names[3], strlen(stat_sb_names[3]), &stat_nlink); + zend_hash_str_update(HASH_OF(return_value), stat_sb_names[4], strlen(stat_sb_names[4]), &stat_uid); + zend_hash_str_update(HASH_OF(return_value), stat_sb_names[5], strlen(stat_sb_names[5]), &stat_gid); + zend_hash_str_update(HASH_OF(return_value), stat_sb_names[6], strlen(stat_sb_names[6]), &stat_rdev); + zend_hash_str_update(HASH_OF(return_value), stat_sb_names[7], strlen(stat_sb_names[7]), &stat_size); + zend_hash_str_update(HASH_OF(return_value), stat_sb_names[8], strlen(stat_sb_names[8]), &stat_atime); + zend_hash_str_update(HASH_OF(return_value), stat_sb_names[9], strlen(stat_sb_names[9]), &stat_mtime); + zend_hash_str_update(HASH_OF(return_value), stat_sb_names[10], strlen(stat_sb_names[10]), &stat_ctime); + zend_hash_str_update(HASH_OF(return_value), stat_sb_names[11], strlen(stat_sb_names[11]), &stat_blksize); + zend_hash_str_update(HASH_OF(return_value), stat_sb_names[12], strlen(stat_sb_names[12]), &stat_blocks); } /* }}} */ @@ -1599,7 +1644,7 @@ PHP_NAMED_FUNCTION(php_if_fstat) PHP_FUNCTION(copy) { char *source, *target; - int source_len, target_len; + size_t source_len, target_len; zval *zcontext = NULL; php_stream_context *context; @@ -1660,7 +1705,7 @@ PHPAPI int php_copy_file_ctx(const char *src, const char *dest, int src_flg, php return FAILURE; } - switch (php_stream_stat_path_ex(dest, PHP_STREAM_URL_STAT_QUIET, &dest_s, ctx)) { + switch (php_stream_stat_path_ex(dest, PHP_STREAM_URL_STAT_QUIET | PHP_STREAM_URL_STAT_NOCACHE, &dest_s, ctx)) { case -1: /* non-statable stream */ goto safe_to_copy; @@ -1736,26 +1781,25 @@ safe_to_copy: PHPAPI PHP_FUNCTION(fread) { zval *arg1; - long len; + zend_long len; php_stream *stream; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &arg1, &len) == FAILURE) { RETURN_FALSE; } - PHP_STREAM_TO_ZVAL(stream, &arg1); + PHP_STREAM_TO_ZVAL(stream, arg1); if (len <= 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length parameter must be greater than 0"); RETURN_FALSE; } - Z_STRVAL_P(return_value) = emalloc(len + 1); + ZVAL_NEW_STR(return_value, zend_string_alloc(len, 0)); Z_STRLEN_P(return_value) = php_stream_read(stream, Z_STRVAL_P(return_value), len); /* needed because recv/read/gzread doesnt put a null at the end*/ Z_STRVAL_P(return_value)[Z_STRLEN_P(return_value)] = 0; - Z_TYPE_P(return_value) = IS_STRING; } /* }}} */ @@ -1765,12 +1809,12 @@ static const char *php_fgetcsv_lookup_trailing_spaces(const char *ptr, size_t le unsigned char last_chars[2] = { 0, 0 }; while (len > 0) { - inc_len = (*ptr == '\0' ? 1: php_mblen(ptr, len)); + inc_len = (*ptr == '\0' ? 1 : php_mblen(ptr, len)); switch (inc_len) { case -2: case -1: inc_len = 1; - php_ignore_value(php_mblen(NULL, 0)); + php_mb_reset(); break; case 0: goto quit_loop; @@ -1797,7 +1841,7 @@ quit_loop: } /* }}} */ -#define FPUTCSV_FLD_CHK(c) memchr(Z_STRVAL(field), c, Z_STRLEN(field)) +#define FPUTCSV_FLD_CHK(c) memchr(field_str->val, c, field_str->len) /* {{{ proto int fputcsv(resource fp, array fields [, string delimiter [, string enclosure [, string escape_char]]]) Format line as CSV and write to file pointer */ @@ -1810,7 +1854,7 @@ PHP_FUNCTION(fputcsv) zval *fp = NULL, *fields = NULL; int ret; char *delimiter_str = NULL, *enclosure_str = NULL, *escape_str = NULL; - int delimiter_str_len = 0, enclosure_str_len = 0, escape_str_len = 0; + size_t delimiter_str_len = 0, enclosure_str_len = 0, escape_str_len = 0; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ra|sss", &fp, &fields, &delimiter_str, &delimiter_str_len, @@ -1854,30 +1898,23 @@ PHP_FUNCTION(fputcsv) escape_char = *escape_str; } - PHP_STREAM_TO_ZVAL(stream, &fp); + PHP_STREAM_TO_ZVAL(stream, fp); ret = php_fputcsv(stream, fields, delimiter, enclosure, escape_char TSRMLS_CC); RETURN_LONG(ret); } /* }}} */ -/* {{{ PHPAPI int php_fputcsv(php_stream *stream, zval *fields, char delimiter, char enclosure, char escape_char TSRMLS_DC) */ -PHPAPI int php_fputcsv(php_stream *stream, zval *fields, char delimiter, char enclosure, char escape_char TSRMLS_DC) +/* {{{ PHPAPI size_t php_fputcsv(php_stream *stream, zval *fields, char delimiter, char enclosure, char escape_char TSRMLS_DC) */ +PHPAPI size_t php_fputcsv(php_stream *stream, zval *fields, char delimiter, char enclosure, char escape_char TSRMLS_DC) { int count, i = 0, ret; - zval **field_tmp = NULL, field; + zval *field_tmp; smart_str csvline = {0}; - HashPosition pos; count = zend_hash_num_elements(Z_ARRVAL_P(fields)); - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(fields), &pos); - while (zend_hash_get_current_data_ex(Z_ARRVAL_P(fields), (void **) &field_tmp, &pos) == SUCCESS) { - field = **field_tmp; - - if (Z_TYPE_PP(field_tmp) != IS_STRING) { - zval_copy_ctor(&field); - convert_to_string(&field); - } + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(fields), field_tmp) { + zend_string *field_str = zval_get_string(field_tmp); /* enclose a field that contains a delimiter, an enclosure character, or a newline */ if (FPUTCSV_FLD_CHK(delimiter) || @@ -1888,8 +1925,8 @@ PHPAPI int php_fputcsv(php_stream *stream, zval *fields, char delimiter, char en FPUTCSV_FLD_CHK('\t') || FPUTCSV_FLD_CHK(' ') ) { - char *ch = Z_STRVAL(field); - char *end = ch + Z_STRLEN(field); + char *ch = field_str->val; + char *end = ch + field_str->len; int escaped = 0; smart_str_appendc(&csvline, enclosure); @@ -1906,23 +1943,19 @@ PHPAPI int php_fputcsv(php_stream *stream, zval *fields, char delimiter, char en } smart_str_appendc(&csvline, enclosure); } else { - smart_str_appendl(&csvline, Z_STRVAL(field), Z_STRLEN(field)); + smart_str_append(&csvline, field_str); } if (++i != count) { smart_str_appendl(&csvline, &delimiter, 1); } - zend_hash_move_forward_ex(Z_ARRVAL_P(fields), &pos); - - if (Z_TYPE_PP(field_tmp) != IS_STRING) { - zval_dtor(&field); - } - } + zend_string_release(field_str); + } ZEND_HASH_FOREACH_END(); smart_str_appendc(&csvline, '\n'); smart_str_0(&csvline); - ret = php_stream_write(stream, csvline.c, csvline.len); + ret = php_stream_write(stream, csvline.s->val, csvline.s->len); smart_str_free(&csvline); @@ -1940,21 +1973,21 @@ PHP_FUNCTION(fgetcsv) /* first section exactly as php_fgetss */ - long len = 0; + zend_long len = 0; size_t buf_len; char *buf; php_stream *stream; { - zval *fd, **len_zv = NULL; + zval *fd, *len_zv = NULL; char *delimiter_str = NULL; - int delimiter_str_len = 0; + size_t delimiter_str_len = 0; char *enclosure_str = NULL; - int enclosure_str_len = 0; + size_t enclosure_str_len = 0; char *escape_str = NULL; - int escape_str_len = 0; + size_t escape_str_len = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|Zsss", + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|zsss", &fd, &len_zv, &delimiter_str, &delimiter_str_len, &enclosure_str, &enclosure_str_len, &escape_str, &escape_str_len) == FAILURE @@ -1998,9 +2031,8 @@ PHP_FUNCTION(fgetcsv) escape = escape_str[0]; } - if (len_zv != NULL && Z_TYPE_PP(len_zv) != IS_NULL) { - convert_to_long_ex(len_zv); - len = Z_LVAL_PP(len_zv); + if (len_zv != NULL && Z_TYPE_P(len_zv) != IS_NULL) { + len = zval_get_long(len_zv); if (len < 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length parameter may not be negative"); RETURN_FALSE; @@ -2011,7 +2043,7 @@ PHP_FUNCTION(fgetcsv) len = -1; } - PHP_STREAM_TO_ZVAL(stream, &fd); + PHP_STREAM_TO_ZVAL(stream, fd); } if (len < 0) { @@ -2038,7 +2070,7 @@ PHPAPI void php_fgetcsv(php_stream *stream, char delimiter, char enclosure, char zend_bool first_field = 1; /* initialize internal state */ - php_ignore_value(php_mblen(NULL, 0)); + php_mb_reset(); /* Now into new section that parses buf for delimiter/enclosure fields */ @@ -2064,7 +2096,7 @@ PHPAPI void php_fgetcsv(php_stream *stream, char delimiter, char enclosure, char tptr = temp; - inc_len = (bptr < limit ? (*bptr == '\0' ? 1: php_mblen(bptr, limit - bptr)): 0); + inc_len = (bptr < limit ? (*bptr == '\0' ? 1 : php_mblen(bptr, limit - bptr)): 0); if (inc_len == 1) { char *tmp = bptr; while ((*tmp != delimiter) && isspace((int)*(unsigned char *)tmp)) { @@ -2153,7 +2185,7 @@ PHPAPI void php_fgetcsv(php_stream *stream, char delimiter, char enclosure, char case -2: case -1: - php_ignore_value(php_mblen(NULL, 0)); + php_mb_reset(); /* break is omitted intentionally */ case 1: /* we need to determine if the enclosure is @@ -2208,7 +2240,7 @@ PHPAPI void php_fgetcsv(php_stream *stream, char delimiter, char enclosure, char } break; } - inc_len = (bptr < limit ? (*bptr == '\0' ? 1: php_mblen(bptr, limit - bptr)): 0); + inc_len = (bptr < limit ? (*bptr == '\0' ? 1 : php_mblen(bptr, limit - bptr)): 0); } quit_loop_2: @@ -2221,7 +2253,7 @@ PHPAPI void php_fgetcsv(php_stream *stream, char delimiter, char enclosure, char case -2: case -1: inc_len = 1; - php_ignore_value(php_mblen(NULL, 0)); + php_mb_reset(); /* break is omitted intentionally */ case 1: if (*bptr == delimiter) { @@ -2232,7 +2264,7 @@ PHPAPI void php_fgetcsv(php_stream *stream, char delimiter, char enclosure, char break; } bptr += inc_len; - inc_len = (bptr < limit ? (*bptr == '\0' ? 1: php_mblen(bptr, limit - bptr)): 0); + inc_len = (bptr < limit ? (*bptr == '\0' ? 1 : php_mblen(bptr, limit - bptr)): 0); } quit_loop_3: @@ -2252,7 +2284,7 @@ PHPAPI void php_fgetcsv(php_stream *stream, char delimiter, char enclosure, char case -2: case -1: inc_len = 1; - php_ignore_value(php_mblen(NULL, 0)); + php_mb_reset(); /* break is omitted intentionally */ case 1: if (*bptr == delimiter) { @@ -2263,7 +2295,7 @@ PHPAPI void php_fgetcsv(php_stream *stream, char delimiter, char enclosure, char break; } bptr += inc_len; - inc_len = (bptr < limit ? (*bptr == '\0' ? 1: php_mblen(bptr, limit - bptr)): 0); + inc_len = (bptr < limit ? (*bptr == '\0' ? 1 : php_mblen(bptr, limit - bptr)): 0); } quit_loop_4: memcpy(tptr, hunk_begin, bptr - hunk_begin); @@ -2277,7 +2309,7 @@ PHPAPI void php_fgetcsv(php_stream *stream, char delimiter, char enclosure, char /* 3. Now pass our field back to php */ *comp_end = '\0'; - add_next_index_stringl(return_value, temp, comp_end - temp, 1); + add_next_index_stringl(return_value, temp, comp_end - temp); } while (inc_len > 0); out: @@ -2294,12 +2326,18 @@ out: PHP_FUNCTION(realpath) { char *filename; - int filename_len; + size_t filename_len; char resolved_path_buff[MAXPATHLEN]; +#ifndef FAST_ZPP if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p", &filename, &filename_len) == FAILURE) { return; } +#else + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_PATH(filename, filename_len) + ZEND_PARSE_PARAMETERS_END(); +#endif if (VCWD_REALPATH(filename, resolved_path_buff)) { if (php_check_open_basedir(resolved_path_buff TSRMLS_CC)) { @@ -2311,7 +2349,7 @@ PHP_FUNCTION(realpath) RETURN_FALSE; } #endif - RETURN_STRING(resolved_path_buff, 1); + RETURN_STRING(resolved_path_buff); } else { RETURN_FALSE; } @@ -2432,8 +2470,8 @@ php_meta_tags_token php_next_meta_token(php_meta_tags_data *md TSRMLS_DC) PHP_FUNCTION(fnmatch) { char *pattern, *filename; - int pattern_len, filename_len; - long flags = 0; + size_t pattern_len, filename_len; + zend_long flags = 0; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "pp|l", &pattern, &pattern_len, &filename, &filename_len, &flags) == FAILURE) { return; @@ -2460,7 +2498,7 @@ PHP_FUNCTION(sys_get_temp_dir) if (zend_parse_parameters_none() == FAILURE) { return; } - RETURN_STRING((char *)php_get_temporary_directory(TSRMLS_C), 1); + RETURN_STRING((char *)php_get_temporary_directory(TSRMLS_C)); } /* }}} */ |