Reduce stack usage in php_resolve_path()

tsrm_realpath() internally always allocates a string. If the out
parameter is provided it gets copied there and freed. What we
were doing here was to first copy the path from the allocated
string to a stack buffer, and then copy it from the stack buffer
to a zend_string. We might as well save one copy and one buffer.
This commit is contained in:
Nikita Popov 2021-07-02 11:41:10 +02:00
parent 3321440166
commit 083d7f5886

View file

@ -458,12 +458,22 @@ PHPAPI int php_fopen_primary_script(zend_file_handle *file_handle)
}
/* }}} */
static zend_string *tsrm_realpath_str(const char *path) {
char *realpath = tsrm_realpath(path, NULL);
if (!realpath) {
return NULL;
}
zend_string *realpath_str = zend_string_init(realpath, strlen(realpath), 0);
efree(realpath);
return realpath_str;
}
/* {{{ php_resolve_path
* Returns the realpath for given filename according to include path
*/
PHPAPI zend_string *php_resolve_path(const char *filename, size_t filename_length, const char *path)
{
char resolved_path[MAXPATHLEN];
zend_string *resolved_path;
char trypath[MAXPATHLEN];
const char *ptr, *end, *p;
const char *actual_path;
@ -479,8 +489,8 @@ PHPAPI zend_string *php_resolve_path(const char *filename, size_t filename_lengt
if ((*p == ':') && (p - filename > 1) && (p[1] == '/') && (p[2] == '/')) {
wrapper = php_stream_locate_url_wrapper(filename, &actual_path, STREAM_OPEN_FOR_INCLUDE);
if (wrapper == &php_plain_files_wrapper) {
if (tsrm_realpath(actual_path, resolved_path)) {
return zend_string_init(resolved_path, strlen(resolved_path), 0);
if ((resolved_path = tsrm_realpath_str(actual_path))) {
return resolved_path;
}
}
return NULL;
@ -499,11 +509,7 @@ PHPAPI zend_string *php_resolve_path(const char *filename, size_t filename_lengt
#endif
!path ||
!*path) {
if (tsrm_realpath(filename, resolved_path)) {
return zend_string_init(resolved_path, strlen(resolved_path), 0);
} else {
return NULL;
}
return tsrm_realpath_str(filename);
}
ptr = path;
@ -559,8 +565,8 @@ PHPAPI zend_string *php_resolve_path(const char *filename, size_t filename_lengt
continue;
}
}
if (tsrm_realpath(actual_path, resolved_path)) {
return zend_string_init(resolved_path, strlen(resolved_path), 0);
if ((resolved_path = tsrm_realpath_str(actual_path))) {
return resolved_path;
}
} /* end provided path */
@ -600,9 +606,7 @@ PHPAPI zend_string *php_resolve_path(const char *filename, size_t filename_lengt
}
}
if (tsrm_realpath(actual_path, resolved_path)) {
return zend_string_init(resolved_path, strlen(resolved_path), 0);
}
return tsrm_realpath_str(actual_path);
}
}