cvs: ZendEngine2(PHP_5_3) / zend.c zend.h zend_vm_def.h zend_vm_execute.h php-src NEWS php-src/main fopen_wrappers.c fopen_wrappers.h main.c
| From: | Dmitry Stogov | Date: | Wed, 05 Mar 2008 13:34:16 +0000 |
| Subject: | cvs: ZendEngine2(PHP_5_3) / zend.c zend.h zend_vm_def.h zend_vm_execute.h php-src NEWS php-src/main fopen_wrappers.c fopen_wrappers.h main.c | ||
| Groups: | php.zend-engine.cvs | ||
| Request: | Send a blank email to php-zend-engine-cvs+get-6469@lists.php.net to get a copy of this message | ||
dmitry Wed Mar 5 13:34:16 2008 UTC
Modified files: (Branch: PHP_5_3)
/php-src NEWS
/php-src/main fopen_wrappers.c fopen_wrappers.h main.c
/ZendEngine2 zend.c zend.h zend_vm_def.h zend_vm_execute.h
Log:
Optimized require_once() and include_once() by eliminationg open() syscall on second usage.
http://cvs.php.net/viewvc.cgi/php-src/NEWS?r1=1.2027.2.547.2.965.2.122&r2=1.2027.2.547.2.965.2.123&diff_format=u Index: php-src/NEWS diff -u php-src/NEWS:1.2027.2.547.2.965.2.122 php-src/NEWS:1.2027.2.547.2.965.2.123 --- php-src/NEWS:1.2027.2.547.2.965.2.122 Tue Mar 4 21:58:07 2008 +++ php-src/NEWS Wed Mar 5 13:34:11 2008 @@ -87,6 +87,8 @@ (Dmitry, Pierre) . Changed exception handling. Now each op_array doesn't contain ZEND_HANDLE_EXCEPTION opcode in the end. (Dmitry) + . Optimized require_once() and include_once() by eliminating fopen(3) on + second usage. (Dmitry) - Improved php.ini handling: (Jani) . Added ".htaccess" style user-defined php.ini files support for CGI/FastCGI . Added support for special [PATH=/opt/httpd/www.example.com/] and http://cvs.php.net/viewvc.cgi/php-src/main/fopen_wrappers.c?r1=1.175.2.3.2.13.2.6&r2=1.175.2.3.2.13.2.7&diff_format=u Index: php-src/main/fopen_wrappers.c diff -u php-src/main/fopen_wrappers.c:1.175.2.3.2.13.2.6 php-src/main/fopen_wrappers.c:1.175.2.3.2.13.2.7 --- php-src/main/fopen_wrappers.c:1.175.2.3.2.13.2.6 Tue Jan 29 14:24:55 2008 +++ php-src/main/fopen_wrappers.c Wed Mar 5 13:34:12 2008 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: fopen_wrappers.c,v 1.175.2.3.2.13.2.6 2008/01/29 14:24:55 dmitry Exp $ */ +/* $Id: fopen_wrappers.c,v 1.175.2.3.2.13.2.7 2008/03/05 13:34:12 dmitry Exp $ */ /* {{{ includes */ @@ -439,6 +439,80 @@ } /* }}} */ +/* {{{ php_resolve_path + * Returns the realpath for given filename according to include path + */ +PHPAPI char *php_resolve_path(const char *filename, int filename_length, const char *path TSRMLS_DC) +{ + char resolved_path[MAXPATHLEN]; + char trypath[MAXPATHLEN]; + char *ptr, *end; + + if (!filename) { + return NULL; + } + + if (*filename == '.' || + IS_ABSOLUTE_PATH(filename, filename_length) || + !path || + !*path) { + if (tsrm_realpath(filename, resolved_path TSRMLS_CC)) { + return estrdup(resolved_path); + } else { + return NULL; + } + } + + ptr = path; + while (ptr && *ptr) { + end = strchr(ptr, DEFAULT_DIR_SEPARATOR); + if (end) { + if ((end-ptr) + 1 + filename_length + 1 >= MAXPATHLEN) { + ptr = end + 1; + continue; + } + memcpy(trypath, ptr, end-ptr); + trypath[end-ptr] = '/'; + memcpy(trypath+(end-ptr)+1, filename, filename_length+1); + ptr = end+1; + } else { + int len = strlen(ptr); + + if (len + 1 + filename_length + 1 >= MAXPATHLEN) { + break; + } + memcpy(trypath, ptr, len); + trypath[len] = '/'; + memcpy(trypath+len+1, filename, filename_length+1); + ptr = NULL; + } + if (tsrm_realpath(trypath, resolved_path TSRMLS_CC)) { + return estrdup(resolved_path); + } + } /* end provided path */ + + /* check in calling scripts' current working directory as a fall back case + */ + if (zend_is_executing(TSRMLS_C)) { + char *exec_fname = zend_get_executed_filename(TSRMLS_C); + int exec_fname_length = strlen(exec_fname); + + while ((--exec_fname_length >= 0) && !IS_SLASH(exec_fname[exec_fname_length])); + if (exec_fname && exec_fname[0] != '[' && + exec_fname_length > 0 && + exec_fname_length + 1 + filename_length + 1 < MAXPATHLEN) { + memcpy(trypath, exec_fname, exec_fname_length + 1); + memcpy(trypath+exec_fname_length + 1, filename, filename_length+1); + if (tsrm_realpath(trypath, resolved_path TSRMLS_CC)) { + return estrdup(resolved_path); + } + } + } + + return NULL; +} +/* }}} */ + /* {{{ php_fopen_with_path * Tries to open a file with a PATH-style list of directories. * If the filename starts with "." or "/", the path is ignored. http://cvs.php.net/viewvc.cgi/php-src/main/fopen_wrappers.h?r1=1.44.2.1.2.2.2.2&r2=1.44.2.1.2.2.2.3&diff_format=u Index: php-src/main/fopen_wrappers.h diff -u php-src/main/fopen_wrappers.h:1.44.2.1.2.2.2.2 php-src/main/fopen_wrappers.h:1.44.2.1.2.2.2.3 --- php-src/main/fopen_wrappers.h:1.44.2.1.2.2.2.2 Mon Dec 31 07:17:17 2007 +++ php-src/main/fopen_wrappers.h Wed Mar 5 13:34:12 2008 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: fopen_wrappers.h,v 1.44.2.1.2.2.2.2 2007/12/31 07:17:17 sebastian Exp $ */ +/* $Id: fopen_wrappers.h,v 1.44.2.1.2.2.2.3 2008/03/05 13:34:12 dmitry Exp $ */ #ifndef FOPEN_WRAPPERS_H #define FOPEN_WRAPPERS_H @@ -33,6 +33,8 @@ PHPAPI int php_check_safe_mode_include_dir(const char *path TSRMLS_DC); +PHPAPI char *php_resolve_path(const char *filename, int filename_len, const char *path TSRMLS_DC); + PHPAPI FILE *php_fopen_with_path(const char *filename, const char *mode, const char *path, char **opened_path TSRMLS_DC); PHPAPI char *php_strip_url_passwd(char *path); http://cvs.php.net/viewvc.cgi/php-src/main/main.c?r1=1.640.2.23.2.57.2.10&r2=1.640.2.23.2.57.2.11&diff_format=u Index: php-src/main/main.c diff -u php-src/main/main.c:1.640.2.23.2.57.2.10 php-src/main/main.c:1.640.2.23.2.57.2.11 --- php-src/main/main.c:1.640.2.23.2.57.2.10 Sat Feb 23 17:06:22 2008 +++ php-src/main/main.c Wed Mar 5 13:34:12 2008 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: main.c,v 1.640.2.23.2.57.2.10 2008/02/23 17:06:22 helly Exp $ */ +/* $Id: main.c,v 1.640.2.23.2.57.2.11 2008/03/05 13:34:12 dmitry Exp $ */ /* {{{ includes */ @@ -1098,6 +1098,12 @@ } /* }}} */ +static char *php_resolve_path_for_zend(const char *filename, int filename_len TSRMLS_DC) /* {{{ */ +{ + return php_resolve_path(filename, filename_len, PG(include_path) TSRMLS_CC); +} +/* }}} */ + /* {{{ php_get_configuration_directive_for_zend */ static int php_get_configuration_directive_for_zend(char *name, uint name_length, zval *contents) @@ -1697,6 +1703,7 @@ zuf.stream_open_function = php_stream_open_for_zend; zuf.vspprintf_function = vspprintf; zuf.getenv_function = sapi_getenv; + zuf.resolve_path_function = php_resolve_path_for_zend; zend_startup(&zuf, NULL, 1); #ifdef ZTS http://cvs.php.net/viewvc.cgi/ZendEngine2/zend.c?r1=1.308.2.12.2.35.2.8&r2=1.308.2.12.2.35.2.9&diff_format=u Index: ZendEngine2/zend.c diff -u ZendEngine2/zend.c:1.308.2.12.2.35.2.8 ZendEngine2/zend.c:1.308.2.12.2.35.2.9 --- ZendEngine2/zend.c:1.308.2.12.2.35.2.8 Sat Feb 23 17:06:19 2008 +++ ZendEngine2/zend.c Wed Mar 5 13:34:12 2008 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend.c,v 1.308.2.12.2.35.2.8 2008/02/23 17:06:19 helly Exp $ */ +/* $Id: zend.c,v 1.308.2.12.2.35.2.9 2008/03/05 13:34:12 dmitry Exp $ */ #include "zend.h" #include "zend_extensions.h" @@ -57,6 +57,7 @@ ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args); int (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap); ZEND_API char *(*zend_getenv)(char *name, size_t name_len TSRMLS_DC); +ZEND_API char *(*zend_resolve_path)(const char *filename, int filename_len TSRMLS_DC); void (*zend_on_timeout)(int seconds TSRMLS_DC); @@ -622,6 +623,7 @@ zend_on_timeout = utility_functions->on_timeout; zend_vspprintf = utility_functions->vspprintf_function; zend_getenv = utility_functions->getenv_function; + zend_resolve_path = utility_functions->resolve_path_function; zend_compile_file = compile_file; zend_compile_string = compile_string; http://cvs.php.net/viewvc.cgi/ZendEngine2/zend.h?r1=1.293.2.11.2.9.2.16&r2=1.293.2.11.2.9.2.17&diff_format=u Index: ZendEngine2/zend.h diff -u ZendEngine2/zend.h:1.293.2.11.2.9.2.16 ZendEngine2/zend.h:1.293.2.11.2.9.2.17 --- ZendEngine2/zend.h:1.293.2.11.2.9.2.16 Tue Jan 22 09:27:46 2008 +++ ZendEngine2/zend.h Wed Mar 5 13:34:12 2008 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend.h,v 1.293.2.11.2.9.2.16 2008/01/22 09:27:46 dmitry Exp $ */ +/* $Id: zend.h,v 1.293.2.11.2.9.2.17 2008/03/05 13:34:12 dmitry Exp $ */ #ifndef ZEND_H #define ZEND_H @@ -463,6 +463,7 @@ int (*stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC); int (*vspprintf_function)(char **pbuf, size_t max_len, const char *format, va_list ap); char *(*getenv_function)(char *name, size_t name_len TSRMLS_DC); + char *(*resolve_path_function)(const char *filename, int filename_len TSRMLS_DC); } zend_utility_functions; typedef struct _zend_utility_values { @@ -590,6 +591,7 @@ extern ZEND_API int (*zend_stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC); extern int (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap); extern ZEND_API char *(*zend_getenv)(char *name, size_t name_len TSRMLS_DC); +extern ZEND_API char *(*zend_resolve_path)(const char *filename, int filename_len TSRMLS_DC); ZEND_API void zend_error(int type, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3); http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_vm_def.h?r1=1.59.2.29.2.48.2.40&r2=1.59.2.29.2.48.2.41&diff_format=u Index: ZendEngine2/zend_vm_def.h diff -u ZendEngine2/zend_vm_def.h:1.59.2.29.2.48.2.40 ZendEngine2/zend_vm_def.h:1.59.2.29.2.48.2.41 --- ZendEngine2/zend_vm_def.h:1.59.2.29.2.48.2.40 Tue Mar 4 11:43:51 2008 +++ ZendEngine2/zend_vm_def.h Wed Mar 5 13:34:12 2008 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_vm_def.h,v 1.59.2.29.2.48.2.40 2008/03/04 11:43:51 dmitry Exp $ */ +/* $Id: zend_vm_def.h,v 1.59.2.29.2.48.2.41 2008/03/05 13:34:12 dmitry Exp $ */ /* If you change this file, please regenerate the zend_vm_execute.h and * zend_vm_opcodes.h files by running: @@ -3054,26 +3054,21 @@ case ZEND_INCLUDE_ONCE: case ZEND_REQUIRE_ONCE: { zend_file_handle file_handle; + char *resolved_path; - if (IS_ABSOLUTE_PATH(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename))) { - cwd_state state; - - state.cwd_length = 0; - state.cwd = malloc(1); - state.cwd[0] = 0; - - failure_retval = (!virtual_file_ex(&state, Z_STRVAL_P(inc_filename), NULL, 1) && - zend_hash_exists(&EG(included_files), state.cwd, state.cwd_length+1)); - - free(state.cwd); + resolved_path = zend_resolve_path(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename) TSRMLS_CC); + if (resolved_path) { + failure_retval = zend_hash_exists(&EG(included_files), resolved_path, strlen(resolved_path)+1); + } else { + resolved_path = Z_STRVAL_P(inc_filename); } if (failure_retval) { - /* do nothing */ - } else if (SUCCESS == zend_stream_open(Z_STRVAL_P(inc_filename), &file_handle TSRMLS_CC)) { + /* do nothing, file already included */ + } else if (SUCCESS == zend_stream_open(resolved_path, &file_handle TSRMLS_CC)) { if (!file_handle.opened_path) { - file_handle.opened_path = estrndup(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename)); + file_handle.opened_path = estrdup(resolved_path); } if (zend_hash_add_empty_element(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path)+1)==SUCCESS) { @@ -3090,6 +3085,9 @@ zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, Z_STRVAL_P(inc_filename)); } } + if (resolved_path != Z_STRVAL_P(inc_filename)) { + efree(resolved_path); + } } break; case ZEND_INCLUDE: http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_vm_execute.h?r1=1.62.2.30.2.49.2.39&r2=1.62.2.30.2.49.2.40&diff_format=u Index: ZendEngine2/zend_vm_execute.h diff -u ZendEngine2/zend_vm_execute.h:1.62.2.30.2.49.2.39 ZendEngine2/zend_vm_execute.h:1.62.2.30.2.49.2.40 --- ZendEngine2/zend_vm_execute.h:1.62.2.30.2.49.2.39 Tue Mar 4 11:43:51 2008 +++ ZendEngine2/zend_vm_execute.h Wed Mar 5 13:34:12 2008 @@ -1663,26 +1663,21 @@ case ZEND_INCLUDE_ONCE: case ZEND_REQUIRE_ONCE: { zend_file_handle file_handle; + char *resolved_path; - if (IS_ABSOLUTE_PATH(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename))) { - cwd_state state; - - state.cwd_length = 0; - state.cwd = malloc(1); - state.cwd[0] = 0; - - failure_retval = (!virtual_file_ex(&state, Z_STRVAL_P(inc_filename), NULL, 1) && - zend_hash_exists(&EG(included_files), state.cwd, state.cwd_length+1)); - - free(state.cwd); + resolved_path = zend_resolve_path(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename) TSRMLS_CC); + if (resolved_path) { + failure_retval = zend_hash_exists(&EG(included_files), resolved_path, strlen(resolved_path)+1); + } else { + resolved_path = Z_STRVAL_P(inc_filename); } if (failure_retval) { - /* do nothing */ - } else if (SUCCESS == zend_stream_open(Z_STRVAL_P(inc_filename), &file_handle TSRMLS_CC)) { + /* do nothing, file already included */ + } else if (SUCCESS == zend_stream_open(resolved_path, &file_handle TSRMLS_CC)) { if (!file_handle.opened_path) { - file_handle.opened_path = estrndup(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename)); + file_handle.opened_path = estrdup(resolved_path); } if (zend_hash_add_empty_element(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path)+1)==SUCCESS) { @@ -1699,6 +1694,9 @@ zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, Z_STRVAL_P(inc_filename)); } } + if (resolved_path != Z_STRVAL_P(inc_filename)) { + efree(resolved_path); + } } break; case ZEND_INCLUDE: @@ -4850,26 +4848,21 @@ case ZEND_INCLUDE_ONCE: case ZEND_REQUIRE_ONCE: { zend_file_handle file_handle; + char *resolved_path; - if (IS_ABSOLUTE_PATH(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename))) { - cwd_state state; - - state.cwd_length = 0; - state.cwd = malloc(1); - state.cwd[0] = 0; - - failure_retval = (!virtual_file_ex(&state, Z_STRVAL_P(inc_filename), NULL, 1) && - zend_hash_exists(&EG(included_files), state.cwd, state.cwd_length+1)); - - free(state.cwd); + resolved_path = zend_resolve_path(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename) TSRMLS_CC); + if (resolved_path) { + failure_retval = zend_hash_exists(&EG(included_files), resolved_path, strlen(resolved_path)+1); + } else { + resolved_path = Z_STRVAL_P(inc_filename); } if (failure_retval) { - /* do nothing */ - } else if (SUCCESS == zend_stream_open(Z_STRVAL_P(inc_filename), &file_handle TSRMLS_CC)) { + /* do nothing, file already included */ + } else if (SUCCESS == zend_stream_open(resolved_path, &file_handle TSRMLS_CC)) { if (!file_handle.opened_path) { - file_handle.opened_path = estrndup(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename)); + file_handle.opened_path = estrdup(resolved_path); } if (zend_hash_add_empty_element(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path)+1)==SUCCESS) { @@ -4886,6 +4879,9 @@ zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, Z_STRVAL_P(inc_filename)); } } + if (resolved_path != Z_STRVAL_P(inc_filename)) { + efree(resolved_path); + } } break; case ZEND_INCLUDE: @@ -8068,26 +8064,21 @@ case ZEND_INCLUDE_ONCE: case ZEND_REQUIRE_ONCE: { zend_file_handle file_handle; + char *resolved_path; - if (IS_ABSOLUTE_PATH(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename))) { - cwd_state state; - - state.cwd_length = 0; - state.cwd = malloc(1); - state.cwd[0] = 0; - - failure_retval = (!virtual_file_ex(&state, Z_STRVAL_P(inc_filename), NULL, 1) && - zend_hash_exists(&EG(included_files), state.cwd, state.cwd_length+1)); - - free(state.cwd); + resolved_path = zend_resolve_path(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename) TSRMLS_CC); + if (resolved_path) { + failure_retval = zend_hash_exists(&EG(included_files), resolved_path, strlen(resolved_path)+1); + } else { + resolved_path = Z_STRVAL_P(inc_filename); } if (failure_retval) { - /* do nothing */ - } else if (SUCCESS == zend_stream_open(Z_STRVAL_P(inc_filename), &file_handle TSRMLS_CC)) { + /* do nothing, file already included */ + } else if (SUCCESS == zend_stream_open(resolved_path, &file_handle TSRMLS_CC)) { if (!file_handle.opened_path) { - file_handle.opened_path = estrndup(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename)); + file_handle.opened_path = estrdup(resolved_path); } if (zend_hash_add_empty_element(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path)+1)==SUCCESS) { @@ -8104,6 +8095,9 @@ zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, Z_STRVAL_P(inc_filename)); } } + if (resolved_path != Z_STRVAL_P(inc_filename)) { + efree(resolved_path); + } } break; case ZEND_INCLUDE: @@ -21750,26 +21744,21 @@ case ZEND_INCLUDE_ONCE: case ZEND_REQUIRE_ONCE: { zend_file_handle file_handle; + char *resolved_path; - if (IS_ABSOLUTE_PATH(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename))) { - cwd_state state; - - state.cwd_length = 0; - state.cwd = malloc(1); - state.cwd[0] = 0; - - failure_retval = (!virtual_file_ex(&state, Z_STRVAL_P(inc_filename), NULL, 1) && - zend_hash_exists(&EG(included_files), state.cwd, state.cwd_length+1)); - - free(state.cwd); + resolved_path = zend_resolve_path(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename) TSRMLS_CC); + if (resolved_path) { + failure_retval = zend_hash_exists(&EG(included_files), resolved_path, strlen(resolved_path)+1); + } else { + resolved_path = Z_STRVAL_P(inc_filename); } if (failure_retval) { - /* do nothing */ - } else if (SUCCESS == zend_stream_open(Z_STRVAL_P(inc_filename), &file_handle TSRMLS_CC)) { + /* do nothing, file already included */ + } else if (SUCCESS == zend_stream_open(resolved_path, &file_handle TSRMLS_CC)) { if (!file_handle.opened_path) { - file_handle.opened_path = estrndup(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename)); + file_handle.opened_path = estrdup(resolved_path); } if (zend_hash_add_empty_element(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path)+1)==SUCCESS) { @@ -21786,6 +21775,9 @@ zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, Z_STRVAL_P(inc_filename)); } } + if (resolved_path != Z_STRVAL_P(inc_filename)) { + efree(resolved_path); + } } break; case ZEND_INCLUDE:
http://cvs.php.net/viewvc.cgi/php-src/NEWS?r1=1.2027.2.547.2.965.2.122&r2=1.2027.2.547.2.965.2.123&diff_format=u Index: php-src/NEWS diff -u php-src/NEWS:1.2027.2.547.2.965.2.122 php-src/NEWS:1.2027.2.547.2.965.2.123 --- php-src/NEWS:1.2027.2.547.2.965.2.122 Tue Mar 4 21:58:07 2008 +++ php-src/NEWS Wed Mar 5 13:34:11 2008 @@ -87,6 +87,8 @@ (Dmitry, Pierre) . Changed exception handling. Now each op_array doesn't contain ZEND_HANDLE_EXCEPTION opcode in the end. (Dmitry) + . Optimized require_once() and include_once() by eliminating fopen(3) on + second usage. (Dmitry) - Improved php.ini handling: (Jani) . Added ".htaccess" style user-defined php.ini files support for CGI/FastCGI . Added support for special [PATH=/opt/httpd/www.example.com/] and http://cvs.php.net/viewvc.cgi/php-src/main/fopen_wrappers.c?r1=1.175.2.3.2.13.2.6&r2=1.175.2.3.2.13.2.7&diff_format=u Index: php-src/main/fopen_wrappers.c diff -u php-src/main/fopen_wrappers.c:1.175.2.3.2.13.2.6 php-src/main/fopen_wrappers.c:1.175.2.3.2.13.2.7 --- php-src/main/fopen_wrappers.c:1.175.2.3.2.13.2.6 Tue Jan 29 14:24:55 2008 +++ php-src/main/fopen_wrappers.c Wed Mar 5 13:34:12 2008 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: fopen_wrappers.c,v 1.175.2.3.2.13.2.6 2008/01/29 14:24:55 dmitry Exp $ */ +/* $Id: fopen_wrappers.c,v 1.175.2.3.2.13.2.7 2008/03/05 13:34:12 dmitry Exp $ */ /* {{{ includes */ @@ -439,6 +439,80 @@ } /* }}} */ +/* {{{ php_resolve_path + * Returns the realpath for given filename according to include path + */ +PHPAPI char *php_resolve_path(const char *filename, int filename_length, const char *path TSRMLS_DC) +{ + char resolved_path[MAXPATHLEN]; + char trypath[MAXPATHLEN]; + char *ptr, *end; + + if (!filename) { + return NULL; + } + + if (*filename == '.' || + IS_ABSOLUTE_PATH(filename, filename_length) || + !path || + !*path) { + if (tsrm_realpath(filename, resolved_path TSRMLS_CC)) { + return estrdup(resolved_path); + } else { + return NULL; + } + } + + ptr = path; + while (ptr && *ptr) { + end = strchr(ptr, DEFAULT_DIR_SEPARATOR); + if (end) { + if ((end-ptr) + 1 + filename_length + 1 >= MAXPATHLEN) { + ptr = end + 1; + continue; + } + memcpy(trypath, ptr, end-ptr); + trypath[end-ptr] = '/'; + memcpy(trypath+(end-ptr)+1, filename, filename_length+1); + ptr = end+1; + } else { + int len = strlen(ptr); + + if (len + 1 + filename_length + 1 >= MAXPATHLEN) { + break; + } + memcpy(trypath, ptr, len); + trypath[len] = '/'; + memcpy(trypath+len+1, filename, filename_length+1); + ptr = NULL; + } + if (tsrm_realpath(trypath, resolved_path TSRMLS_CC)) { + return estrdup(resolved_path); + } + } /* end provided path */ + + /* check in calling scripts' current working directory as a fall back case + */ + if (zend_is_executing(TSRMLS_C)) { + char *exec_fname = zend_get_executed_filename(TSRMLS_C); + int exec_fname_length = strlen(exec_fname); + + while ((--exec_fname_length >= 0) && !IS_SLASH(exec_fname[exec_fname_length])); + if (exec_fname && exec_fname[0] != '[' && + exec_fname_length > 0 && + exec_fname_length + 1 + filename_length + 1 < MAXPATHLEN) { + memcpy(trypath, exec_fname, exec_fname_length + 1); + memcpy(trypath+exec_fname_length + 1, filename, filename_length+1); + if (tsrm_realpath(trypath, resolved_path TSRMLS_CC)) { + return estrdup(resolved_path); + } + } + } + + return NULL; +} +/* }}} */ + /* {{{ php_fopen_with_path * Tries to open a file with a PATH-style list of directories. * If the filename starts with "." or "/", the path is ignored. http://cvs.php.net/viewvc.cgi/php-src/main/fopen_wrappers.h?r1=1.44.2.1.2.2.2.2&r2=1.44.2.1.2.2.2.3&diff_format=u Index: php-src/main/fopen_wrappers.h diff -u php-src/main/fopen_wrappers.h:1.44.2.1.2.2.2.2 php-src/main/fopen_wrappers.h:1.44.2.1.2.2.2.3 --- php-src/main/fopen_wrappers.h:1.44.2.1.2.2.2.2 Mon Dec 31 07:17:17 2007 +++ php-src/main/fopen_wrappers.h Wed Mar 5 13:34:12 2008 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: fopen_wrappers.h,v 1.44.2.1.2.2.2.2 2007/12/31 07:17:17 sebastian Exp $ */ +/* $Id: fopen_wrappers.h,v 1.44.2.1.2.2.2.3 2008/03/05 13:34:12 dmitry Exp $ */ #ifndef FOPEN_WRAPPERS_H #define FOPEN_WRAPPERS_H @@ -33,6 +33,8 @@ PHPAPI int php_check_safe_mode_include_dir(const char *path TSRMLS_DC); +PHPAPI char *php_resolve_path(const char *filename, int filename_len, const char *path TSRMLS_DC); + PHPAPI FILE *php_fopen_with_path(const char *filename, const char *mode, const char *path, char **opened_path TSRMLS_DC); PHPAPI char *php_strip_url_passwd(char *path); http://cvs.php.net/viewvc.cgi/php-src/main/main.c?r1=1.640.2.23.2.57.2.10&r2=1.640.2.23.2.57.2.11&diff_format=u Index: php-src/main/main.c diff -u php-src/main/main.c:1.640.2.23.2.57.2.10 php-src/main/main.c:1.640.2.23.2.57.2.11 --- php-src/main/main.c:1.640.2.23.2.57.2.10 Sat Feb 23 17:06:22 2008 +++ php-src/main/main.c Wed Mar 5 13:34:12 2008 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: main.c,v 1.640.2.23.2.57.2.10 2008/02/23 17:06:22 helly Exp $ */ +/* $Id: main.c,v 1.640.2.23.2.57.2.11 2008/03/05 13:34:12 dmitry Exp $ */ /* {{{ includes */ @@ -1098,6 +1098,12 @@ } /* }}} */ +static char *php_resolve_path_for_zend(const char *filename, int filename_len TSRMLS_DC) /* {{{ */ +{ + return php_resolve_path(filename, filename_len, PG(include_path) TSRMLS_CC); +} +/* }}} */ + /* {{{ php_get_configuration_directive_for_zend */ static int php_get_configuration_directive_for_zend(char *name, uint name_length, zval *contents) @@ -1697,6 +1703,7 @@ zuf.stream_open_function = php_stream_open_for_zend; zuf.vspprintf_function = vspprintf; zuf.getenv_function = sapi_getenv; + zuf.resolve_path_function = php_resolve_path_for_zend; zend_startup(&zuf, NULL, 1); #ifdef ZTS http://cvs.php.net/viewvc.cgi/ZendEngine2/zend.c?r1=1.308.2.12.2.35.2.8&r2=1.308.2.12.2.35.2.9&diff_format=u Index: ZendEngine2/zend.c diff -u ZendEngine2/zend.c:1.308.2.12.2.35.2.8 ZendEngine2/zend.c:1.308.2.12.2.35.2.9 --- ZendEngine2/zend.c:1.308.2.12.2.35.2.8 Sat Feb 23 17:06:19 2008 +++ ZendEngine2/zend.c Wed Mar 5 13:34:12 2008 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend.c,v 1.308.2.12.2.35.2.8 2008/02/23 17:06:19 helly Exp $ */ +/* $Id: zend.c,v 1.308.2.12.2.35.2.9 2008/03/05 13:34:12 dmitry Exp $ */ #include "zend.h" #include "zend_extensions.h" @@ -57,6 +57,7 @@ ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args); int (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap); ZEND_API char *(*zend_getenv)(char *name, size_t name_len TSRMLS_DC); +ZEND_API char *(*zend_resolve_path)(const char *filename, int filename_len TSRMLS_DC); void (*zend_on_timeout)(int seconds TSRMLS_DC); @@ -622,6 +623,7 @@ zend_on_timeout = utility_functions->on_timeout; zend_vspprintf = utility_functions->vspprintf_function; zend_getenv = utility_functions->getenv_function; + zend_resolve_path = utility_functions->resolve_path_function; zend_compile_file = compile_file; zend_compile_string = compile_string; http://cvs.php.net/viewvc.cgi/ZendEngine2/zend.h?r1=1.293.2.11.2.9.2.16&r2=1.293.2.11.2.9.2.17&diff_format=u Index: ZendEngine2/zend.h diff -u ZendEngine2/zend.h:1.293.2.11.2.9.2.16 ZendEngine2/zend.h:1.293.2.11.2.9.2.17 --- ZendEngine2/zend.h:1.293.2.11.2.9.2.16 Tue Jan 22 09:27:46 2008 +++ ZendEngine2/zend.h Wed Mar 5 13:34:12 2008 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend.h,v 1.293.2.11.2.9.2.16 2008/01/22 09:27:46 dmitry Exp $ */ +/* $Id: zend.h,v 1.293.2.11.2.9.2.17 2008/03/05 13:34:12 dmitry Exp $ */ #ifndef ZEND_H #define ZEND_H @@ -463,6 +463,7 @@ int (*stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC); int (*vspprintf_function)(char **pbuf, size_t max_len, const char *format, va_list ap); char *(*getenv_function)(char *name, size_t name_len TSRMLS_DC); + char *(*resolve_path_function)(const char *filename, int filename_len TSRMLS_DC); } zend_utility_functions; typedef struct _zend_utility_values { @@ -590,6 +591,7 @@ extern ZEND_API int (*zend_stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC); extern int (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap); extern ZEND_API char *(*zend_getenv)(char *name, size_t name_len TSRMLS_DC); +extern ZEND_API char *(*zend_resolve_path)(const char *filename, int filename_len TSRMLS_DC); ZEND_API void zend_error(int type, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3); http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_vm_def.h?r1=1.59.2.29.2.48.2.40&r2=1.59.2.29.2.48.2.41&diff_format=u Index: ZendEngine2/zend_vm_def.h diff -u ZendEngine2/zend_vm_def.h:1.59.2.29.2.48.2.40 ZendEngine2/zend_vm_def.h:1.59.2.29.2.48.2.41 --- ZendEngine2/zend_vm_def.h:1.59.2.29.2.48.2.40 Tue Mar 4 11:43:51 2008 +++ ZendEngine2/zend_vm_def.h Wed Mar 5 13:34:12 2008 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_vm_def.h,v 1.59.2.29.2.48.2.40 2008/03/04 11:43:51 dmitry Exp $ */ +/* $Id: zend_vm_def.h,v 1.59.2.29.2.48.2.41 2008/03/05 13:34:12 dmitry Exp $ */ /* If you change this file, please regenerate the zend_vm_execute.h and * zend_vm_opcodes.h files by running: @@ -3054,26 +3054,21 @@ case ZEND_INCLUDE_ONCE: case ZEND_REQUIRE_ONCE: { zend_file_handle file_handle; + char *resolved_path; - if (IS_ABSOLUTE_PATH(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename))) { - cwd_state state; - - state.cwd_length = 0; - state.cwd = malloc(1); - state.cwd[0] = 0; - - failure_retval = (!virtual_file_ex(&state, Z_STRVAL_P(inc_filename), NULL, 1) && - zend_hash_exists(&EG(included_files), state.cwd, state.cwd_length+1)); - - free(state.cwd); + resolved_path = zend_resolve_path(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename) TSRMLS_CC); + if (resolved_path) { + failure_retval = zend_hash_exists(&EG(included_files), resolved_path, strlen(resolved_path)+1); + } else { + resolved_path = Z_STRVAL_P(inc_filename); } if (failure_retval) { - /* do nothing */ - } else if (SUCCESS == zend_stream_open(Z_STRVAL_P(inc_filename), &file_handle TSRMLS_CC)) { + /* do nothing, file already included */ + } else if (SUCCESS == zend_stream_open(resolved_path, &file_handle TSRMLS_CC)) { if (!file_handle.opened_path) { - file_handle.opened_path = estrndup(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename)); + file_handle.opened_path = estrdup(resolved_path); } if (zend_hash_add_empty_element(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path)+1)==SUCCESS) { @@ -3090,6 +3085,9 @@ zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, Z_STRVAL_P(inc_filename)); } } + if (resolved_path != Z_STRVAL_P(inc_filename)) { + efree(resolved_path); + } } break; case ZEND_INCLUDE: http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_vm_execute.h?r1=1.62.2.30.2.49.2.39&r2=1.62.2.30.2.49.2.40&diff_format=u Index: ZendEngine2/zend_vm_execute.h diff -u ZendEngine2/zend_vm_execute.h:1.62.2.30.2.49.2.39 ZendEngine2/zend_vm_execute.h:1.62.2.30.2.49.2.40 --- ZendEngine2/zend_vm_execute.h:1.62.2.30.2.49.2.39 Tue Mar 4 11:43:51 2008 +++ ZendEngine2/zend_vm_execute.h Wed Mar 5 13:34:12 2008 @@ -1663,26 +1663,21 @@ case ZEND_INCLUDE_ONCE: case ZEND_REQUIRE_ONCE: { zend_file_handle file_handle; + char *resolved_path; - if (IS_ABSOLUTE_PATH(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename))) { - cwd_state state; - - state.cwd_length = 0; - state.cwd = malloc(1); - state.cwd[0] = 0; - - failure_retval = (!virtual_file_ex(&state, Z_STRVAL_P(inc_filename), NULL, 1) && - zend_hash_exists(&EG(included_files), state.cwd, state.cwd_length+1)); - - free(state.cwd); + resolved_path = zend_resolve_path(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename) TSRMLS_CC); + if (resolved_path) { + failure_retval = zend_hash_exists(&EG(included_files), resolved_path, strlen(resolved_path)+1); + } else { + resolved_path = Z_STRVAL_P(inc_filename); } if (failure_retval) { - /* do nothing */ - } else if (SUCCESS == zend_stream_open(Z_STRVAL_P(inc_filename), &file_handle TSRMLS_CC)) { + /* do nothing, file already included */ + } else if (SUCCESS == zend_stream_open(resolved_path, &file_handle TSRMLS_CC)) { if (!file_handle.opened_path) { - file_handle.opened_path = estrndup(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename)); + file_handle.opened_path = estrdup(resolved_path); } if (zend_hash_add_empty_element(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path)+1)==SUCCESS) { @@ -1699,6 +1694,9 @@ zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, Z_STRVAL_P(inc_filename)); } } + if (resolved_path != Z_STRVAL_P(inc_filename)) { + efree(resolved_path); + } } break; case ZEND_INCLUDE: @@ -4850,26 +4848,21 @@ case ZEND_INCLUDE_ONCE: case ZEND_REQUIRE_ONCE: { zend_file_handle file_handle; + char *resolved_path; - if (IS_ABSOLUTE_PATH(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename))) { - cwd_state state; - - state.cwd_length = 0; - state.cwd = malloc(1); - state.cwd[0] = 0; - - failure_retval = (!virtual_file_ex(&state, Z_STRVAL_P(inc_filename), NULL, 1) && - zend_hash_exists(&EG(included_files), state.cwd, state.cwd_length+1)); - - free(state.cwd); + resolved_path = zend_resolve_path(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename) TSRMLS_CC); + if (resolved_path) { + failure_retval = zend_hash_exists(&EG(included_files), resolved_path, strlen(resolved_path)+1); + } else { + resolved_path = Z_STRVAL_P(inc_filename); } if (failure_retval) { - /* do nothing */ - } else if (SUCCESS == zend_stream_open(Z_STRVAL_P(inc_filename), &file_handle TSRMLS_CC)) { + /* do nothing, file already included */ + } else if (SUCCESS == zend_stream_open(resolved_path, &file_handle TSRMLS_CC)) { if (!file_handle.opened_path) { - file_handle.opened_path = estrndup(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename)); + file_handle.opened_path = estrdup(resolved_path); } if (zend_hash_add_empty_element(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path)+1)==SUCCESS) { @@ -4886,6 +4879,9 @@ zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, Z_STRVAL_P(inc_filename)); } } + if (resolved_path != Z_STRVAL_P(inc_filename)) { + efree(resolved_path); + } } break; case ZEND_INCLUDE: @@ -8068,26 +8064,21 @@ case ZEND_INCLUDE_ONCE: case ZEND_REQUIRE_ONCE: { zend_file_handle file_handle; + char *resolved_path; - if (IS_ABSOLUTE_PATH(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename))) { - cwd_state state; - - state.cwd_length = 0; - state.cwd = malloc(1); - state.cwd[0] = 0; - - failure_retval = (!virtual_file_ex(&state, Z_STRVAL_P(inc_filename), NULL, 1) && - zend_hash_exists(&EG(included_files), state.cwd, state.cwd_length+1)); - - free(state.cwd); + resolved_path = zend_resolve_path(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename) TSRMLS_CC); + if (resolved_path) { + failure_retval = zend_hash_exists(&EG(included_files), resolved_path, strlen(resolved_path)+1); + } else { + resolved_path = Z_STRVAL_P(inc_filename); } if (failure_retval) { - /* do nothing */ - } else if (SUCCESS == zend_stream_open(Z_STRVAL_P(inc_filename), &file_handle TSRMLS_CC)) { + /* do nothing, file already included */ + } else if (SUCCESS == zend_stream_open(resolved_path, &file_handle TSRMLS_CC)) { if (!file_handle.opened_path) { - file_handle.opened_path = estrndup(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename)); + file_handle.opened_path = estrdup(resolved_path); } if (zend_hash_add_empty_element(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path)+1)==SUCCESS) { @@ -8104,6 +8095,9 @@ zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, Z_STRVAL_P(inc_filename)); } } + if (resolved_path != Z_STRVAL_P(inc_filename)) { + efree(resolved_path); + } } break; case ZEND_INCLUDE: @@ -21750,26 +21744,21 @@ case ZEND_INCLUDE_ONCE: case ZEND_REQUIRE_ONCE: { zend_file_handle file_handle; + char *resolved_path; - if (IS_ABSOLUTE_PATH(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename))) { - cwd_state state; - - state.cwd_length = 0; - state.cwd = malloc(1); - state.cwd[0] = 0; - - failure_retval = (!virtual_file_ex(&state, Z_STRVAL_P(inc_filename), NULL, 1) && - zend_hash_exists(&EG(included_files), state.cwd, state.cwd_length+1)); - - free(state.cwd); + resolved_path = zend_resolve_path(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename) TSRMLS_CC); + if (resolved_path) { + failure_retval = zend_hash_exists(&EG(included_files), resolved_path, strlen(resolved_path)+1); + } else { + resolved_path = Z_STRVAL_P(inc_filename); } if (failure_retval) { - /* do nothing */ - } else if (SUCCESS == zend_stream_open(Z_STRVAL_P(inc_filename), &file_handle TSRMLS_CC)) { + /* do nothing, file already included */ + } else if (SUCCESS == zend_stream_open(resolved_path, &file_handle TSRMLS_CC)) { if (!file_handle.opened_path) { - file_handle.opened_path = estrndup(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename)); + file_handle.opened_path = estrdup(resolved_path); } if (zend_hash_add_empty_element(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path)+1)==SUCCESS) { @@ -21786,6 +21775,9 @@ zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, Z_STRVAL_P(inc_filename)); } } + if (resolved_path != Z_STRVAL_P(inc_filename)) { + efree(resolved_path); + } } break; case ZEND_INCLUDE: