diff options
author | Dmitry Stogov <dmitry@zend.com> | 2021-03-16 20:31:36 +0300 |
---|---|---|
committer | Dmitry Stogov <dmitry@zend.com> | 2021-03-16 20:31:36 +0300 |
commit | c732ab400af92c54eee47c487a56009f1d79dd5d (patch) | |
tree | 083d31748450932114a7667aae9235cde030efcb /main | |
parent | 9bbeb0555b6b842ebd44e08510ff3f3226237544 (diff) | |
download | php-git-c732ab400af92c54eee47c487a56009f1d79dd5d.tar.gz |
Change Zend Stream API to use zend_string* instead of char*.
This allows to eliminate re-calculation of string lenght and hash value.
See the detailed list of changes in UPGRADING.INTERNALS.
Diffstat (limited to 'main')
-rw-r--r-- | main/fopen_wrappers.c | 50 | ||||
-rw-r--r-- | main/main.c | 45 | ||||
-rw-r--r-- | main/php_ini.c | 15 | ||||
-rw-r--r-- | main/php_main.h | 2 | ||||
-rw-r--r-- | main/php_streams.h | 3 | ||||
-rw-r--r-- | main/streams/streams.c | 10 |
6 files changed, 74 insertions, 51 deletions
diff --git a/main/fopen_wrappers.c b/main/fopen_wrappers.c index 633c5e3b2b..8d26b9cfc6 100644 --- a/main/fopen_wrappers.c +++ b/main/fopen_wrappers.c @@ -339,7 +339,7 @@ static FILE *php_fopen_and_set_opened_path(const char *path, const char *mode, z PHPAPI int php_fopen_primary_script(zend_file_handle *file_handle) { char *path_info; - char *filename = NULL; + zend_string *filename = NULL; zend_string *resolved_path = NULL; size_t length; bool orig_display_errors; @@ -378,9 +378,10 @@ PHPAPI int php_fopen_primary_script(zend_file_handle *file_handle) pw = getpwnam(user); #endif if (pw && pw->pw_dir) { - spprintf(&filename, 0, "%s%c%s%c%s", pw->pw_dir, PHP_DIR_SEPARATOR, PG(user_dir), PHP_DIR_SEPARATOR, s + 1); /* Safe */ - } else { - filename = SG(request_info).path_translated; + filename = zend_strpprintf(0, "%s%c%s%c%s", pw->pw_dir, PHP_DIR_SEPARATOR, PG(user_dir), PHP_DIR_SEPARATOR, s + 1); /* Safe */ + } else if (SG(request_info).path_translated) { + filename = zend_string_init(SG(request_info).path_translated, + strlen(SG(request_info).path_translated), 0); } #if defined(ZTS) && defined(HAVE_GETPWNAM_R) && defined(_SC_GETPW_R_SIZE_MAX) efree(pwbuf); @@ -391,29 +392,29 @@ PHPAPI int php_fopen_primary_script(zend_file_handle *file_handle) if (PG(doc_root) && path_info && (length = strlen(PG(doc_root))) && IS_ABSOLUTE_PATH(PG(doc_root), length)) { size_t path_len = strlen(path_info); - filename = emalloc(length + path_len + 2); + filename = zend_string_alloc(length + path_len + 2, 0); memcpy(filename, PG(doc_root), length); - if (!IS_SLASH(filename[length - 1])) { /* length is never 0 */ - filename[length++] = PHP_DIR_SEPARATOR; + if (!IS_SLASH(ZSTR_VAL(filename)[length - 1])) { /* length is never 0 */ + ZSTR_VAL(filename)[length++] = PHP_DIR_SEPARATOR; } if (IS_SLASH(path_info[0])) { length--; } - strncpy(filename + length, path_info, path_len + 1); - } else { - filename = SG(request_info).path_translated; + strncpy(ZSTR_VAL(filename) + length, path_info, path_len + 1); + ZSTR_LEN(filename) = length + path_len; + } else if (SG(request_info).path_translated) { + filename = zend_string_init(SG(request_info).path_translated, + strlen(SG(request_info).path_translated), 0); } if (filename) { - resolved_path = zend_resolve_path(filename, strlen(filename)); + resolved_path = zend_resolve_path(filename); } if (!resolved_path) { - if (SG(request_info).path_translated != filename) { - if (filename) { - efree(filename); - } + if (filename) { + zend_string_release(filename); } /* we have to free SG(request_info).path_translated here because * php_destroy_request_info assumes that it will get @@ -429,13 +430,13 @@ PHPAPI int php_fopen_primary_script(zend_file_handle *file_handle) orig_display_errors = PG(display_errors); PG(display_errors) = 0; - if (zend_stream_open(filename, file_handle) == FAILURE) { + zend_stream_init_filename_ex(file_handle, filename); + file_handle->primary_script = 1; + if (filename) { + zend_string_delref(filename); + } + if (zend_stream_open(file_handle) == FAILURE) { PG(display_errors) = orig_display_errors; - if (SG(request_info).path_translated != filename) { - if (filename) { - efree(filename); - } - } if (SG(request_info).path_translated) { efree(SG(request_info).path_translated); SG(request_info).path_translated = NULL; @@ -444,13 +445,6 @@ PHPAPI int php_fopen_primary_script(zend_file_handle *file_handle) } PG(display_errors) = orig_display_errors; - if (SG(request_info).path_translated != filename) { - if (SG(request_info).path_translated) { - efree(SG(request_info).path_translated); - } - SG(request_info).path_translated = filename; - } - return SUCCESS; } /* }}} */ diff --git a/main/main.c b/main/main.c index 1aa41da672..a32c89739f 100644 --- a/main/main.c +++ b/main/main.c @@ -1442,9 +1442,10 @@ PHP_FUNCTION(set_time_limit) /* }}} */ /* {{{ php_fopen_wrapper_for_zend */ -static FILE *php_fopen_wrapper_for_zend(const char *filename, zend_string **opened_path) +static FILE *php_fopen_wrapper_for_zend(zend_string *filename, zend_string **opened_path) { - return php_stream_open_wrapper_as_file((char *)filename, "rb", USE_PATH|REPORT_ERRORS|STREAM_OPEN_FOR_INCLUDE, opened_path); + *opened_path = filename; + return php_stream_open_wrapper_as_file(ZSTR_VAL(filename), "rb", USE_PATH|REPORT_ERRORS|STREAM_OPEN_FOR_INCLUDE|STREAM_OPEN_FOR_ZEND_STREAM, opened_path); } /* }}} */ @@ -1472,20 +1473,25 @@ static size_t php_zend_stream_fsizer(void *handle) /* {{{ */ } /* }}} */ -static zend_result php_stream_open_for_zend(const char *filename, zend_file_handle *handle) /* {{{ */ +static zend_result php_stream_open_for_zend(zend_file_handle *handle) /* {{{ */ { - return php_stream_open_for_zend_ex(filename, handle, USE_PATH|REPORT_ERRORS|STREAM_OPEN_FOR_INCLUDE); + return php_stream_open_for_zend_ex(handle, USE_PATH|REPORT_ERRORS|STREAM_OPEN_FOR_INCLUDE); } /* }}} */ -PHPAPI zend_result php_stream_open_for_zend_ex(const char *filename, zend_file_handle *handle, int mode) /* {{{ */ +PHPAPI zend_result php_stream_open_for_zend_ex(zend_file_handle *handle, int mode) /* {{{ */ { zend_string *opened_path; - php_stream *stream = php_stream_open_wrapper((char *)filename, "rb", mode, &opened_path); + zend_string *filename; + php_stream *stream; + + ZEND_ASSERT(handle->type == ZEND_HANDLE_FILENAME); + opened_path = filename = handle->filename; + stream = php_stream_open_wrapper((char *)ZSTR_VAL(filename), "rb", mode | STREAM_OPEN_FOR_ZEND_STREAM, &opened_path); if (stream) { memset(handle, 0, sizeof(zend_file_handle)); handle->type = ZEND_HANDLE_STREAM; - handle->filename = (char*)filename; + handle->filename = filename; handle->opened_path = opened_path; handle->handle.stream.handle = stream; handle->handle.stream.reader = (zend_stream_reader_t)_php_stream_read; @@ -1503,9 +1509,9 @@ PHPAPI zend_result php_stream_open_for_zend_ex(const char *filename, zend_file_h } /* }}} */ -static zend_string *php_resolve_path_for_zend(const char *filename, size_t filename_len) /* {{{ */ +static zend_string *php_resolve_path_for_zend(zend_string *filename) /* {{{ */ { - return php_resolve_path(filename, filename_len, PG(include_path)); + return php_resolve_path(ZSTR_VAL(filename), ZSTR_LEN(filename), PG(include_path)); } /* }}} */ @@ -2142,9 +2148,11 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod /* this will read in php.ini, set up the configuration parameters, load zend extensions and register php function extensions to be loaded later */ + zend_stream_init(); if (php_init_config() == FAILURE) { return FAILURE; } + zend_stream_shutdown(); /* Register PHP core ini entries */ REGISTER_INI_ENTRIES(); @@ -2450,18 +2458,18 @@ PHPAPI int php_execute_script(zend_file_handle *primary_file) #else php_ignore_value(VCWD_GETCWD(old_cwd, OLD_CWD_SIZE-1)); #endif - VCWD_CHDIR_FILE(primary_file->filename); + VCWD_CHDIR_FILE(ZSTR_VAL(primary_file->filename)); } /* Only lookup the real file path and add it to the included_files list if already opened * otherwise it will get opened and added to the included_files list in zend_execute_scripts */ - if (primary_file->filename && - strcmp("Standard input code", primary_file->filename) && + if (primary_file->filename && + strcmp("Standard input code", ZSTR_VAL(primary_file->filename)) && primary_file->opened_path == NULL && primary_file->type != ZEND_HANDLE_FILENAME ) { - if (expand_filepath(primary_file->filename, realfile)) { + if (expand_filepath(ZSTR_VAL(primary_file->filename), realfile)) { primary_file->opened_path = zend_string_init(realfile, strlen(realfile), 0); zend_hash_add_empty_element(&EG(included_files), primary_file->opened_path); } @@ -2490,6 +2498,14 @@ PHPAPI int php_execute_script(zend_file_handle *primary_file) retval = (zend_execute_scripts(ZEND_REQUIRE, NULL, 3, prepend_file_p, primary_file, append_file_p) == SUCCESS); } zend_end_try(); + if (prepend_file_p) { + zend_destroy_file_handle(prepend_file_p); + } + + if (append_file_p) { + zend_destroy_file_handle(append_file_p); + } + if (EG(exception)) { zend_try { zend_exception_error(EG(exception), E_ERROR); @@ -2533,7 +2549,7 @@ PHPAPI int php_execute_simple_script(zend_file_handle *primary_file, zval *ret) if (primary_file->filename && !(SG(options) & SAPI_OPTION_NO_CHDIR)) { php_ignore_value(VCWD_GETCWD(old_cwd, OLD_CWD_SIZE-1)); - VCWD_CHDIR_FILE(primary_file->filename); + VCWD_CHDIR_FILE(ZSTR_VAL(primary_file->filename)); } zend_execute_scripts(ZEND_REQUIRE, ret, 1, primary_file); } zend_end_try(); @@ -2609,7 +2625,6 @@ PHPAPI int php_lint_script(zend_file_handle *file) zend_try { op_array = zend_compile_file(file, ZEND_INCLUDE); - zend_destroy_file_handle(file); if (op_array) { destroy_op_array(op_array); diff --git a/main/php_ini.c b/main/php_ini.c index 0fa3a33365..44c70c6a23 100644 --- a/main/php_ini.c +++ b/main/php_ini.c @@ -616,15 +616,14 @@ int php_init_config(void) { zval tmp; - ZVAL_NEW_STR(&tmp, zend_string_init(fh.filename, strlen(fh.filename), 1)); + ZVAL_NEW_STR(&tmp, zend_string_init(filename, strlen(filename), 1)); zend_hash_str_update(&configuration_hash, "cfg_file_path", sizeof("cfg_file_path")-1, &tmp); if (opened_path) { zend_string_release_ex(opened_path, 0); - } else { - efree((char *)fh.filename); } php_ini_opened_path = zend_strndup(Z_STRVAL(tmp), Z_STRLEN(tmp)); } + zend_destroy_file_handle(&fh); } /* Check for PHP_INI_SCAN_DIR environment variable to override/set config file scan directory */ @@ -693,6 +692,7 @@ int php_init_config(void) zend_llist_add_element(&scanned_ini_list, &p); } } + zend_destroy_file_handle(&fh); } } free(namelist[i]); @@ -771,17 +771,20 @@ PHPAPI int php_parse_user_ini_file(const char *dirname, const char *ini_filename if (VCWD_STAT(ini_file, &sb) == 0) { if (S_ISREG(sb.st_mode)) { zend_file_handle fh; + int ret = FAILURE; + zend_stream_init_fp(&fh, VCWD_FOPEN(ini_file, "r"), ini_file); if (fh.handle.fp) { /* Reset active ini section */ RESET_ACTIVE_INI_HASH(); - if (zend_parse_ini_file(&fh, 1, ZEND_INI_SCANNER_NORMAL, (zend_ini_parser_cb_t) php_ini_parser_cb, target_hash) == SUCCESS) { + ret = zend_parse_ini_file(&fh, 1, ZEND_INI_SCANNER_NORMAL, (zend_ini_parser_cb_t) php_ini_parser_cb, target_hash); + if (ret == SUCCESS) { /* FIXME: Add parsed file to the list of user files read? */ - return SUCCESS; } - return FAILURE; } + zend_destroy_file_handle(&fh); + return ret; } } return FAILURE; diff --git a/main/php_main.h b/main/php_main.h index ee27209fbe..1beedd853e 100644 --- a/main/php_main.h +++ b/main/php_main.h @@ -40,7 +40,7 @@ PHPAPI void php_handle_aborted_connection(void); PHPAPI int php_handle_auth_data(const char *auth); PHPAPI void php_html_puts(const char *str, size_t siz); -PHPAPI int php_stream_open_for_zend_ex(const char *filename, zend_file_handle *handle, int mode); +PHPAPI int php_stream_open_for_zend_ex(zend_file_handle *handle, int mode); /* environment module */ extern int php_init_environ(void); diff --git a/main/php_streams.h b/main/php_streams.h index f7196b8437..3c1417ddd1 100644 --- a/main/php_streams.h +++ b/main/php_streams.h @@ -554,6 +554,9 @@ END_EXTERN_C() /* Allow blocking reads on anonymous pipes on Windows. */ #define STREAM_USE_BLOCKING_PIPE 0x00008000 +/* this flag is only used by include/require functions */ +#define STREAM_OPEN_FOR_ZEND_STREAM 0x00010000 + int php_init_stream_wrappers(int module_number); int php_shutdown_stream_wrappers(int module_number); void php_shutdown_stream_hashes(void); diff --git a/main/streams/streams.c b/main/streams/streams.c index 96d3aeb41e..9bf7444412 100644 --- a/main/streams/streams.c +++ b/main/streams/streams.c @@ -2043,10 +2043,14 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(const char *path, const char *mod php_stream_wrapper *wrapper = NULL; const char *path_to_open; int persistent = options & STREAM_OPEN_PERSISTENT; + zend_string *path_str = NULL; zend_string *resolved_path = NULL; char *copy_of_path = NULL; if (opened_path) { + if (options & STREAM_OPEN_FOR_ZEND_STREAM) { + path_str = *opened_path; + } *opened_path = NULL; } @@ -2056,7 +2060,11 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(const char *path, const char *mod } if (options & USE_PATH) { - resolved_path = zend_resolve_path(path, strlen(path)); + if (path_str) { + resolved_path = zend_resolve_path(path_str); + } else { + resolved_path = php_resolve_path(path, strlen(path), PG(include_path)); + } if (resolved_path) { path = ZSTR_VAL(resolved_path); /* we've found this file, don't re-check include_path or run realpath */ |