Marcus Boerger wrote: > Hello Gregory, > > Monday, March 24, 2008, 2:28:00 PM, you wrote: > > >> Index: main/fopen_wrappers.c >> =================================================================== >> RCS file: /repository/php-src/main/fopen_wrappers.c,v >> retrieving revision 1.175.2.3.2.13.2.9 >> diff -u -r1.175.2.3.2.13.2.9 fopen_wrappers.c >> --- main/fopen_wrappers.c 24 Mar 2008 09:30:41 -0000 >> 1.175.2.3.2.13.2.9 >> +++ main/fopen_wrappers.c 24 Mar 2008 13:24:34 -0000 >> @@ -473,7 +473,15 @@ >> >> ptr = path; >> while (ptr && *ptr) { >> - end = strchr(ptr, DEFAULT_DIR_SEPARATOR); >> + /* Check for stream wrapper */ >> + int is_stream_wrapper = 0; >> + >> + for (p = ptr; isalnum((int)*p) || *p == '+' || *p == '-' || >> *p == '.'; p++); >> + if ((*p == ':') && (p - ptr > 1) && (p[1] == '/') && (p[2] >> == '/')) { >> > However how about: > if ((p > ptr) && !memcmp(p, "://", 3)) { this would unfortunately break UNC paths on unix, which start with //. We have to verify that the stuff between : and : in the previous thing is a valid stream wrapper, which means it can only be alphanumeric/+/-/. However, I imagine the memcmp could be applied as if ((*p == ':') && (p - ptr > 1) && !memcmp(p, "://", 3))
Would that really be faster? > I think prefixinf with STREAMS_ would be good. OK, updated and attached Greg
Index: main/fopen_wrappers.c =================================================================== RCS file: /repository/php-src/main/fopen_wrappers.c,v retrieving revision 1.175.2.3.2.13.2.9 diff -u -r1.175.2.3.2.13.2.9 fopen_wrappers.c --- main/fopen_wrappers.c 24 Mar 2008 09:30:41 -0000 1.175.2.3.2.13.2.9 +++ main/fopen_wrappers.c 24 Mar 2008 13:46:39 -0000 @@ -473,7 +473,15 @@ ptr = path; while (ptr && *ptr) { - end = strchr(ptr, DEFAULT_DIR_SEPARATOR); + /* Check for stream wrapper */ + int is_stream_wrapper = 0; + + for (p = ptr; isalnum((int)*p) || *p == '+' || *p == '-' || *p == '.'; p++); + if ((*p == ':') && (p - ptr > 1) && (p[1] == '/') && (p[2] == '/')) { + p += 2; + is_stream_wrapper = 1; + } + end = strchr(p, DEFAULT_DIR_SEPARATOR); if (end) { if ((end-ptr) + 1 + filename_length + 1 >= MAXPATHLEN) { ptr = end + 1; @@ -494,6 +502,25 @@ memcpy(trypath+len+1, filename, filename_length+1); ptr = NULL; } + if (is_stream_wrapper) { + char *actual; + php_stream_wrapper *wrapper = php_stream_locate_url_wrapper(trypath, &actual, STREAM_OPEN_FOR_INCLUDE TSRMLS_CC); + + if (!wrapper) { + continue; + } else if (wrapper == &php_plain_files_wrapper) { + strncpy(trypath, actual, MAXPATHLEN); + } else { + if (wrapper->wops->url_stat) { + php_stream_statbuf ssb; + + if (SUCCESS == wrapper->wops->url_stat(wrapper, trypath, 0, &ssb, NULL TSRMLS_CC)) { + return estrdup(trypath); + } + } + continue; + } + } if (tsrm_realpath(trypath, resolved_path TSRMLS_CC)) { return estrdup(resolved_path); } @@ -511,6 +538,29 @@ 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); + + /* Check for stream wrapper */ + for (p = trypath; isalnum((int)*p) || *p == '+' || *p == '-' || *p == '.'; p++); + if ((*p == ':') && (p - trypath > 1) && (p[1] == '/') && (p[2] == '/')) { + char *actual; + php_stream_wrapper *wrapper = php_stream_locate_url_wrapper(trypath, &actual, STREAM_OPEN_FOR_INCLUDE TSRMLS_CC); + + if (!wrapper) { + return NULL; + } else if (wrapper == &php_plain_files_wrapper) { + strncpy(trypath, actual, MAXPATHLEN); + } else { + if (wrapper->wops->url_stat) { + php_stream_statbuf ssb; + + if (SUCCESS == wrapper->wops->url_stat(wrapper, trypath, 0, &ssb, NULL TSRMLS_CC)) { + return estrdup(trypath); + } + } + return NULL; + } + } + if (tsrm_realpath(trypath, resolved_path TSRMLS_CC)) { return estrdup(resolved_path); } Index: main/php_streams.h =================================================================== RCS file: /repository/php-src/main/php_streams.h,v retrieving revision 1.103.2.1.2.4.2.2 diff -u -r1.103.2.1.2.4.2.2 php_streams.h --- main/php_streams.h 31 Dec 2007 07:17:17 -0000 1.103.2.1.2.4.2.2 +++ main/php_streams.h 24 Mar 2008 13:46:39 -0000 @@ -511,6 +511,12 @@ /* don't check allow_url_fopen and allow_url_include */ #define STREAM_DISABLE_URL_PROTECTION 0x00002000 +/* assume the path passed in exists and is fully expanded, avoiding syscalls */ +#define STREAM_ASSUME_REALPATH 0x00004000 + +/* assume the path passed in does not exist, and fail (plain wrapper only) */ +#define STREAM_REALPATH_FAILED 0x00008000 + /* Antique - no longer has meaning */ #define IGNORE_URL_WIN 0 Index: main/streams/plain_wrapper.c =================================================================== RCS file: /repository/php-src/main/streams/plain_wrapper.c,v retrieving revision 1.52.2.6.2.23.2.5 diff -u -r1.52.2.6.2.23.2.5 plain_wrapper.c --- main/streams/plain_wrapper.c 31 Dec 2007 07:17:17 -0000 1.52.2.6.2.23.2.5 +++ main/streams/plain_wrapper.c 24 Mar 2008 13:46:40 -0000 @@ -892,9 +892,16 @@ } return NULL; } - - if ((realpath = expand_filepath(filename, NULL TSRMLS_CC)) == NULL) { - return NULL; + + if (options & STREAM_ASSUME_REALPATH) { + realpath = estrdup(filename); + } else { + if (options & STREAM_REALPATH_FAILED) { + return NULL; + } + if ((realpath = expand_filepath(filename, NULL TSRMLS_CC)) == NULL) { + return NULL; + } } if (persistent) { Index: main/streams/streams.c =================================================================== RCS file: /repository/php-src/main/streams/streams.c,v retrieving revision 1.82.2.6.2.18.2.5 diff -u -r1.82.2.6.2.18.2.5 streams.c --- main/streams/streams.c 12 Jan 2008 15:50:57 -0000 1.82.2.6.2.18.2.5 +++ main/streams/streams.c 24 Mar 2008 13:46:41 -0000 @@ -1773,7 +1773,7 @@ php_stream *stream = NULL; php_stream_wrapper *wrapper = NULL; char *path_to_open; - int persistent = options & STREAM_OPEN_PERSISTENT; + int persistent = options & STREAM_OPEN_PERSISTENT, free_path = 0; char *copy_of_path = NULL; @@ -1787,9 +1787,26 @@ path_to_open = path; + if (options & USE_PATH) { + path_to_open = zend_resolve_path(path, strlen(path) TSRMLS_CC); + if (path_to_open) { + path = path_to_open; + free_path = 1; + /* we've found this file, don't re-check include_path or run realpath */ + options |= STREAM_ASSUME_REALPATH; + options &= ~USE_PATH; + } else { + options |= STREAM_REALPATH_FAILED; + path_to_open = path; + } + } + wrapper = php_stream_locate_url_wrapper(path, &path_to_open, options TSRMLS_CC); if (options & STREAM_USE_URL && (!wrapper || !wrapper->is_url)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "This function may only be used against URLs"); + if (free_path) { + efree(path); + } return NULL; } @@ -1809,6 +1826,9 @@ php_stream_wrapper_log_error(wrapper, options ^ REPORT_ERRORS TSRMLS_CC, "wrapper does not support persistent streams"); php_stream_close(stream); + if (free_path) { + efree(path); + } stream = NULL; } @@ -1836,12 +1856,18 @@ (options & STREAM_WILL_CAST) ? PHP_STREAM_PREFER_STDIO : PHP_STREAM_NO_PREFERENCE)) { case PHP_STREAM_UNCHANGED: + if (free_path) { + efree(path); + } return stream; case PHP_STREAM_RELEASED: if (newstream->orig_path) { pefree(newstream->orig_path, persistent); } newstream->orig_path = pestrdup(path, persistent); + if (free_path) { + efree(path); + } return newstream; default: php_stream_close(stream); @@ -1880,6 +1906,9 @@ pefree(copy_of_path, persistent); } #endif + if (free_path) { + efree(path); + } return stream; } /* }}} */
-- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php