From d02dff1363a3e9030f2ac78541ab3642574e07a5 Mon Sep 17 00:00:00 2001 From: Greg Beaver Date: Thu, 20 Mar 2008 23:59:07 +0000 Subject: [PATCH] save work - sandbox is completely f**ed up, have to rm -rf and start again This *SHOULD* fix issues, but I can't get run-tests to work reliably to be absolutely sure --- ext/phar/func_interceptors.c | 7 +- ext/phar/phar.c | 227 +------------------------ ext/phar/phar_internal.h | 5 +- ext/phar/util.c | 316 +++++++++++++++++++++++++---------- 4 files changed, 242 insertions(+), 313 deletions(-) diff --git a/ext/phar/func_interceptors.c b/ext/phar/func_interceptors.c index b611427932..c8d5de4b53 100644 --- a/ext/phar/func_interceptors.c +++ b/ext/phar/func_interceptors.c @@ -134,9 +134,8 @@ PHAR_FUNC(phar_file_get_contents) /* {{{ */ if (!IS_ABSOLUTE_PATH(filename, filename_len)) { /* retrieving a file defaults to within the current directory, so use this if possible */ if (SUCCESS == (zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **) &pphar))) { - name = entry; if (use_include_path) { - if (!(entry = phar_find_in_include_path(entry, pphar TSRMLS_CC))) { + if (!(entry = phar_find_in_include_path(entry, entry_len, NULL TSRMLS_CC))) { /* this file is not in the phar, use the original path */ efree(arch); efree(old); @@ -243,10 +242,12 @@ PHAR_FUNC(phar_fopen) /* {{{ */ /* retrieving a file defaults to within the current directory, so use this if possible */ if (SUCCESS == (zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **) &pphar))) { if (use_include_path) { - if (!(entry = phar_find_in_include_path(entry, pphar TSRMLS_CC))) { + name = entry; + if (!(entry = phar_find_in_include_path(entry, entry_len, NULL TSRMLS_CC))) { /* this file is not in the phar, use the original path */ efree(old); efree(arch); + efree(name); goto skip_phar; } efree(old); diff --git a/ext/phar/phar.c b/ext/phar/phar.c index 571a26e14e..8f584defb1 100644 --- a/ext/phar/phar.c +++ b/ext/phar/phar.c @@ -2584,7 +2584,6 @@ static long stream_fteller_for_zend(void *handle TSRMLS_DC) /* {{{ */ zend_op_array *(*phar_orig_compile_file)(zend_file_handle *file_handle, int type TSRMLS_DC); #if PHP_VERSION_ID >= 50300 #define phar_orig_zend_open zend_stream_open_function -static char *(*phar_save_resolve_path)(const char *filename, int filename_len TSRMLS_DC); #else int (*phar_orig_zend_open)(const char *filename, zend_file_handle *handle TSRMLS_DC); #endif @@ -2598,227 +2597,7 @@ int (*phar_orig_zend_open)(const char *filename, zend_file_handle *handle TSRMLS */ char *phar_resolve_path(const char *filename, int filename_len TSRMLS_DC) { -#if PHP_VERSION_ID >= 50300 - char *path, *fname, *arch, *entry, *ret, *test; - int arch_len, entry_len; - - if (!zend_is_executing(TSRMLS_C) || !PHAR_G(cwd)) { - return phar_save_resolve_path(filename, filename_len TSRMLS_CC); - } - fname = zend_get_executed_filename(TSRMLS_C); - if (SUCCESS != phar_split_fname(fname, strlen(fname), &arch, &arch_len, &entry, &entry_len TSRMLS_CC)) { - return phar_save_resolve_path(filename, filename_len TSRMLS_CC); - } - if (*filename == '.') { - phar_archive_data **pphar; - int try_len; - - if (SUCCESS != (zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **) &pphar))) { - efree(arch); - efree(entry); - return phar_save_resolve_path(filename, filename_len TSRMLS_CC); - } - efree(entry); - test = phar_fix_filepath(estrndup(filename, filename_len), &try_len, 1 TSRMLS_CC); - if (zend_hash_exists(&((*pphar)->manifest), test + 1, try_len - 1)) { - spprintf(&ret, 0, "phar://%s%s", arch, test); - efree(arch); - efree(test); - return ret; - } - } - efree(entry); - spprintf(&path, MAXPATHLEN, "phar://%s/%s%c%s", arch, PHAR_G(cwd), DEFAULT_DIR_SEPARATOR, PG(include_path)); - efree(arch); - ret = php_resolve_path(filename, filename_len, path TSRMLS_CC); - efree(path); - return ret; -#else /* PHP 5.2 */ - char resolved_path[MAXPATHLEN]; - char trypath[MAXPATHLEN]; - char *ptr, *end, *path = PG(include_path); - php_stream_wrapper *wrapper; - const char *p; - int n = 0; - char *fname, *arch, *entry, *ret, *test; - int arch_len, entry_len; - - if (!filename) { - return NULL; - } - - if (!zend_is_executing(TSRMLS_C) || !PHAR_G(cwd)) { - goto doit; - } - fname = zend_get_executed_filename(TSRMLS_C); - if (SUCCESS != phar_split_fname(fname, strlen(fname), &arch, &arch_len, &entry, &entry_len TSRMLS_CC)) { - goto doit; - } - - if (*filename == '.') { - phar_archive_data **pphar; - int try_len; - - if (SUCCESS != (zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **) &pphar))) { - efree(arch); - efree(entry); - goto doit; - } - efree(entry); - test = phar_fix_filepath(estrndup(filename, filename_len), &try_len, 1 TSRMLS_CC); - if (zend_hash_exists(&((*pphar)->manifest), test + 1, try_len - 1)) { - spprintf(&ret, 0, "phar://%s%s", arch, test); - efree(arch); - efree(test); - return ret; - } - efree(test); - } - efree(arch); - efree(entry); - -doit: - if (*filename == '.' || - IS_ABSOLUTE_PATH(filename, filename_len) || - !path || - !*path) { - if (tsrm_realpath(filename, resolved_path TSRMLS_CC)) { - return estrdup(resolved_path); - } else { - return NULL; - } - } - /* test for stream wrappers and return */ - for (p = filename; p - filename < filename_len && (isalnum((int)*p) || *p == '+' || *p == '-' || *p == '.'); p++) { - n++; - } - - if (n < filename_len - 3 && (*p == ':') && (!strncmp("//", p+1, 2) || ( filename_len > 4 && !memcmp("data", filename, 4)))) { - /* found stream wrapper, this is an absolute path until stream wrappers implement realpath */ - return estrndup(filename, filename_len); - } - - ptr = (char *) path; - while (ptr && *ptr) { - int len, is_stream_wrapper = 0, maybe_stream = 1; - - end = strchr(ptr, DEFAULT_DIR_SEPARATOR); -#ifndef PHP_WIN32 - /* search for stream wrapper */ - if (end - ptr <= 1) { - maybe_stream = 0; - goto not_stream; - } - for (p = ptr, n = 0; p < end && (isalnum((int)*p) || *p == '+' || *p == '-' || *p == '.'); p++) { - n++; - } - - if (n == end - ptr && *p && !strncmp("//", p+1, 2)) { - is_stream_wrapper = 1; - /* seek to real end of include_path portion */ - end = strchr(end + 1, DEFAULT_DIR_SEPARATOR); - } else { - maybe_stream = 0; - } -not_stream: -#endif - if (end) { - if ((end-ptr) + 1 + filename_len + 1 >= MAXPATHLEN) { - ptr = end + 1; - continue; - } - memcpy(trypath, ptr, end-ptr); - len = end-ptr; - trypath[end-ptr] = '/'; - memcpy(trypath+(end-ptr)+1, filename, filename_len+1); - ptr = end+1; - } else { - len = strlen(ptr); - - if (len + 1 + filename_len + 1 >= MAXPATHLEN) { - break; - } - memcpy(trypath, ptr, len); - trypath[len] = '/'; - memcpy(trypath+len+1, filename, filename_len+1); - ptr = NULL; - } - - if (!is_stream_wrapper && maybe_stream) { - /* search for stream wrapper */ - for (p = trypath, n = 0; isalnum((int)*p) || *p == '+' || *p == '-' || *p == '.'; p++) { - n++; - } - } - - if (is_stream_wrapper || (n < len - 3 && (*p == ':') && (n > 1) && (!strncmp("//", p+1, 2) || !memcmp("data", trypath, 4)))) { - char *actual; - - wrapper = php_stream_locate_url_wrapper(trypath, &actual, STREAM_OPEN_FOR_INCLUDE TSRMLS_CC); - if (wrapper == &php_plain_files_wrapper) { - strncpy(trypath, actual, MAXPATHLEN); - } else if (!wrapper) { - /* if wrapper is NULL, there was a mal-formed include_path stream wrapper, so skip this ptr */ - continue; - } 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); - } - } /* 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); - const char *p; - int n = 0; - - 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_len + 1 < MAXPATHLEN) { - memcpy(trypath, exec_fname, exec_fname_length + 1); - memcpy(trypath+exec_fname_length + 1, filename, filename_len+1); - - /* search for stream wrapper */ - for (p = trypath; isalnum((int)*p) || *p == '+' || *p == '-' || *p == '.'; p++) { - n++; - } - if (n < exec_fname_length - 3 && (*p == ':') && (n > 1) && (!strncmp("//", p+1, 2) || !memcmp("data", trypath, 4))) { - char *actual; - - wrapper = php_stream_locate_url_wrapper(trypath, &actual, STREAM_OPEN_FOR_INCLUDE TSRMLS_CC); - if (wrapper == &php_plain_files_wrapper) { - /* this should never technically happen, but we'll leave it here for completeness */ - strncpy(trypath, actual, MAXPATHLEN); - } else if (!wrapper) { - /* if wrapper is NULL, there was a mal-formed include_path stream wrapper - this also should be impossible */ - return NULL; - } else { - return estrdup(trypath); - } - } - if (tsrm_realpath(trypath, resolved_path TSRMLS_CC)) { - return estrdup(resolved_path); - } - } - } - - return NULL; -#endif /* PHP 5.2 */ + return phar_find_in_include_path((char *) filename, filename_len, NULL TSRMLS_CC); } static zend_op_array *phar_compile_file(zend_file_handle *file_handle, int type TSRMLS_DC) /* {{{ */ @@ -2911,7 +2690,7 @@ int phar_zend_open(const char *filename, zend_file_handle *handle TSRMLS_DC) /* } } /* retrieving an include within the current directory, so use this if possible */ - if (!(entry = phar_find_in_include_path((char *) filename, pphar TSRMLS_CC))) { + if (!(entry = phar_find_in_include_path((char *) filename, strlen(filename), pphar TSRMLS_CC))) { /* this file is not in the phar, use the original path */ goto skip_phar; } @@ -2951,7 +2730,7 @@ int phar_zend_open(const char *filename, zend_file_handle *handle TSRMLS_DC) /* phar_archive_data **pphar; /* retrieving an include within the current directory, so use this if possible */ if (SUCCESS == (zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **) &pphar))) { - if (!(entry = phar_find_in_include_path(entry, pphar TSRMLS_CC))) { + if (!(entry = phar_find_in_include_path(entry, entry_len, pphar TSRMLS_CC))) { /* this file is not in the phar, use the original path */ if (SUCCESS == phar_orig_zend_open(filename, handle TSRMLS_CC)) { if (SUCCESS == phar_mount_entry(*pphar, handle->opened_path ? handle->opened_path : (char *) filename, strlen(handle->opened_path ? handle->opened_path : filename), (char *) filename, strlen(filename) TSRMLS_CC)) { diff --git a/ext/phar/phar_internal.h b/ext/phar/phar_internal.h index 68963ebe30..2eca75f7ea 100755 --- a/ext/phar/phar_internal.h +++ b/ext/phar/phar_internal.h @@ -342,6 +342,9 @@ BEGIN_EXTERN_C() int phar_has_bz2; int phar_has_zlib; +#if PHP_VERSION_ID >= 50300 +char *(*phar_save_resolve_path)(const char *filename, int filename_len TSRMLS_DC); +#endif #ifdef PHP_WIN32 char *tsrm_strtok_r(char *s, const char *delim, char **last); @@ -378,7 +381,7 @@ char * phar_compress_filter(phar_entry_info * entry, int return_unknown); void phar_rename_archive(phar_archive_data *phar, char *ext, zend_bool compress TSRMLS_DC); int phar_mount_entry(phar_archive_data *phar, char *filename, int filename_len, char *path, int path_len TSRMLS_DC); -char *phar_find_in_include_path(char *file, phar_archive_data **phar TSRMLS_DC); +char *phar_find_in_include_path(char *file, int file_len, phar_archive_data **pphar TSRMLS_DC); char *phar_fix_filepath(char *path, int *new_len, int use_cwd TSRMLS_DC); phar_entry_info * phar_open_jit(phar_archive_data *phar, phar_entry_info *entry, php_stream *fp, char **error, int for_write TSRMLS_DC); diff --git a/ext/phar/util.c b/ext/phar/util.c index f965c03317..6f38a17c8a 100644 --- a/ext/phar/util.c +++ b/ext/phar/util.c @@ -241,115 +241,261 @@ int phar_mount_entry(phar_archive_data *phar, char *filename, int filename_len, return FAILURE; } -char *phar_find_in_include_path(char *file, phar_archive_data **pphar TSRMLS_DC) /* {{{ */ +char *phar_find_in_include_path(char *filename, int filename_len, phar_archive_data **pphar TSRMLS_DC) /* {{{ */ { - char *path = PG(include_path), *pathbuf, *ptr, *end; - char *trypath; - phar_archive_data *blank = NULL, *self; +#if PHP_VERSION_ID >= 50300 + char *path, *fname, *arch, *entry, *ret, *test; + int arch_len, entry_len; - if (!pphar) { - pphar = ␣ - self = NULL; - } else { - self = *pphar; + if (pphar) { + *pphar = NULL; + } + + if (!zend_is_executing(TSRMLS_C) || !PHAR_G(cwd)) { + return phar_save_resolve_path(filename, filename_len TSRMLS_CC); } - if (!path || (path && !*path)) { - return file; + fname = zend_get_executed_filename(TSRMLS_C); + if (SUCCESS != phar_split_fname(fname, strlen(fname), &arch, &arch_len, &entry, &entry_len TSRMLS_CC)) { + return phar_save_resolve_path(filename, filename_len TSRMLS_CC); } + if (*filename == '.') { + int try_len; - /* check in provided path */ - /* append the calling scripts' current working directory - * as a fall back case - */ - spprintf(&pathbuf, 0, "%s%c.", path, DEFAULT_DIR_SEPARATOR); + if (SUCCESS != (zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **) &pphar))) { + efree(arch); + efree(entry); + return phar_save_resolve_path(filename, filename_len TSRMLS_CC); + } + efree(entry); + test = phar_fix_filepath(estrndup(filename, filename_len), &try_len, 1 TSRMLS_CC); + if (zend_hash_exists(&((*pphar)->manifest), test + 1, try_len - 1)) { + spprintf(&ret, 0, "phar://%s%s", arch, test); + efree(arch); + efree(test); + return ret; + } + } + efree(entry); + spprintf(&path, MAXPATHLEN, "phar://%s/%s%c%s", arch, PHAR_G(cwd), DEFAULT_DIR_SEPARATOR, PG(include_path)); + efree(arch); + ret = php_resolve_path(filename, filename_len, path TSRMLS_CC); + efree(path); + if (ret && strlen(ret) > 8 && !strncmp(ret, "phar://", 7)) { + char *arch, *entry; + int arch_len, entry_len, ret_len; - ptr = pathbuf; + ret_len = strlen(ret); + /* found phar:// */ - while (ptr && *ptr) { + if (SUCCESS != phar_split_fname(ret, ret_len, &arch, &arch_len, &entry, &entry_len TSRMLS_CC)) { + return ret; + } + zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **) &pphar); + efree(arch); + efree(entry); + } + return ret; +#else /* PHP 5.2 */ + char resolved_path[MAXPATHLEN]; + char trypath[MAXPATHLEN]; + char *ptr, *end, *path = PG(include_path); + php_stream_wrapper *wrapper; + const char *p; + int n = 0; + char *fname, *arch, *entry, *ret, *test; + int arch_len, entry_len; + + if (!filename) { + return NULL; + } + + if (!zend_is_executing(TSRMLS_C) || !PHAR_G(cwd)) { + goto doit; + } + fname = zend_get_executed_filename(TSRMLS_C); + if (SUCCESS != phar_split_fname(fname, strlen(fname), &arch, &arch_len, &entry, &entry_len TSRMLS_CC)) { + goto doit; + } + + if (*filename == '.') { + phar_archive_data **pphar; int try_len; - char *test; + + if (SUCCESS != (zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **) &pphar))) { + efree(arch); + efree(entry); + goto doit; + } + efree(entry); + test = phar_fix_filepath(estrndup(filename, filename_len), &try_len, 1 TSRMLS_CC); + if (zend_hash_exists(&((*pphar)->manifest), test + 1, try_len - 1)) { + spprintf(&ret, 0, "phar://%s%s", arch, test); + efree(arch); + efree(test); + return ret; + } + efree(test); + } + efree(arch); + efree(entry); + +doit: + if (*filename == '.' || + IS_ABSOLUTE_PATH(filename, filename_len) || + !path || + !*path) { + if (tsrm_realpath(filename, resolved_path TSRMLS_CC)) { + return estrdup(resolved_path); + } else { + return NULL; + } + } + /* test for stream wrappers and return */ + for (p = filename; p - filename < filename_len && (isalnum((int)*p) || *p == '+' || *p == '-' || *p == '.'); p++) { + n++; + } + + if (n < filename_len - 3 && (*p == ':') && (!strncmp("//", p+1, 2) || ( filename_len > 4 && !memcmp("data", filename, 4)))) { + /* found stream wrapper, this is an absolute path until stream wrappers implement realpath */ + return estrndup(filename, filename_len); + } + + ptr = (char *) path; + while (ptr && *ptr) { + int len, is_stream_wrapper = 0, maybe_stream = 1; end = strchr(ptr, DEFAULT_DIR_SEPARATOR); - /* check for phar:// */ - if (end - ptr == 4 && !strncmp(ptr, "phar", 4)) { - char *arch, *entry; - int arch_len, entry_len; +#ifndef PHP_WIN32 + /* search for stream wrapper */ + if (end - ptr <= 1) { + maybe_stream = 0; + goto not_stream; + } + for (p = ptr, n = 0; p < end && (isalnum((int)*p) || *p == '+' || *p == '-' || *p == '.'); p++) { + n++; + } - /* found phar:// */ + if (n == end - ptr && *p && !strncmp("//", p+1, 2)) { + is_stream_wrapper = 1; + /* seek to real end of include_path portion */ end = strchr(end + 1, DEFAULT_DIR_SEPARATOR); - if (end != NULL) { - *end = '\0'; - end++; - } - - if (SUCCESS != phar_split_fname(ptr, end - ptr, &arch, &arch_len, &entry, &entry_len TSRMLS_CC)) { + } else { + maybe_stream = 0; + } +not_stream: +#endif + if (end) { + if ((end-ptr) + 1 + filename_len + 1 >= MAXPATHLEN) { + ptr = end + 1; continue; } - if (SUCCESS != (zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **) &pphar))) { - efree(arch); - efree(entry); - continue; + memcpy(trypath, ptr, end-ptr); + len = end-ptr; + trypath[end-ptr] = '/'; + memcpy(trypath+(end-ptr)+1, filename, filename_len+1); + ptr = end+1; + } else { + len = strlen(ptr); + + if (len + 1 + filename_len + 1 >= MAXPATHLEN) { + break; } - try_len = spprintf(&trypath, MAXPATHLEN, "%s/%s", entry, file); - efree(entry); - test = phar_fix_filepath(trypath, &try_len, 0 TSRMLS_CC); - if (zend_hash_exists(&((*pphar)->manifest), test + 1, try_len - 1)) { - efree(pathbuf); - spprintf(&trypath, 0, "phar://%s%s", arch, test); - efree(arch); - efree(test); - return trypath; + memcpy(trypath, ptr, len); + trypath[len] = '/'; + memcpy(trypath+len+1, filename, filename_len+1); + ptr = NULL; + } + + if (!is_stream_wrapper && maybe_stream) { + /* search for stream wrapper */ + for (p = trypath, n = 0; isalnum((int)*p) || *p == '+' || *p == '-' || *p == '.'; p++) { + n++; } - if (zend_hash_num_elements(&((*pphar)->mounted_dirs))) { - if (phar_get_entry_info_dir(*pphar, test + 1, try_len - 1, 0, NULL TSRMLS_CC)) { - spprintf(&trypath, 0, "phar://%s%s", arch, test); - efree(arch); - efree(test); - return trypath; + } + + if (is_stream_wrapper || (n < len - 3 && (*p == ':') && (n > 1) && (!strncmp("//", p+1, 2) || !memcmp("data", trypath, 4)))) { + char *actual; + + wrapper = php_stream_locate_url_wrapper(trypath, &actual, STREAM_OPEN_FOR_INCLUDE TSRMLS_CC); + if (wrapper == &php_plain_files_wrapper) { + strncpy(trypath, actual, MAXPATHLEN); + } else if (!wrapper) { + /* if wrapper is NULL, there was a mal-formed include_path stream wrapper, so skip this ptr */ + continue; + } else { + if (wrapper->wops->url_stat) { + php_stream_statbuf ssb; + + if (SUCCESS == wrapper->wops->url_stat(wrapper, trypath, 0, &ssb, NULL TSRMLS_CC)) { + if (wrapper == &php_stream_phar_wrapper) { + char *arch, *entry; + int arch_len, entry_len, ret_len; + + ret_len = strlen(trypath); + /* found phar:// */ + + if (SUCCESS != phar_split_fname(trypath, ret_len, &arch, &arch_len, &entry, &entry_len TSRMLS_CC)) { + return estrndup(trypath, ret_len); + } + zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **) &pphar); + efree(arch); + efree(entry); + return estrndup(trypath, ret_len); + } + return estrdup(trypath); + } } + continue; } - efree(test); - *pphar = self; - ptr = end; - continue; - } - if (end != NULL) { - *end = '\0'; - end++; - } - if (*ptr == '\0') { - goto stream_skip; } - if (!*pphar || ptr[0] != '.') { - ptr = end; - continue; - } - /* relative path in include_path starting with ".", look inside current phar, if any */ - try_len = spprintf(&trypath, MAXPATHLEN, "%s/%s", ptr, file); - test = phar_fix_filepath(trypath, &try_len, 1 TSRMLS_CC); - if (zend_hash_exists(&((*pphar)->manifest), test + 1, try_len - 1)) { - char *save = test; - efree(pathbuf); - test = estrndup(test + 1, try_len - 1); - efree(save); - return test; + + if (tsrm_realpath(trypath, resolved_path TSRMLS_CC)) { + return estrdup(resolved_path); } - if (zend_hash_num_elements(&((*pphar)->mounted_dirs))) { - if (phar_get_entry_info_dir(*pphar, test + 1, try_len - 1, 0, NULL TSRMLS_CC)) { - char *save = test; - efree(pathbuf); - test = estrndup(test + 1, try_len - 1); - efree(save); - return test; + } /* 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); + const char *p; + int n = 0; + + 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_len + 1 < MAXPATHLEN) { + memcpy(trypath, exec_fname, exec_fname_length + 1); + memcpy(trypath+exec_fname_length + 1, filename, filename_len+1); + + /* search for stream wrapper */ + for (p = trypath; isalnum((int)*p) || *p == '+' || *p == '-' || *p == '.'; p++) { + n++; + } + if (n < exec_fname_length - 3 && (*p == ':') && (n > 1) && (!strncmp("//", p+1, 2) || !memcmp("data", trypath, 4))) { + char *actual; + + wrapper = php_stream_locate_url_wrapper(trypath, &actual, STREAM_OPEN_FOR_INCLUDE TSRMLS_CC); + if (wrapper == &php_plain_files_wrapper) { + /* this should never technically happen, but we'll leave it here for completeness */ + strncpy(trypath, actual, MAXPATHLEN); + } else if (!wrapper) { + /* if wrapper is NULL, there was a mal-formed include_path stream wrapper + this also should be impossible */ + return NULL; + } else { + return estrdup(trypath); + } + } + if (tsrm_realpath(trypath, resolved_path TSRMLS_CC)) { + return estrdup(resolved_path); } } - efree(test); -stream_skip: - ptr = end; - } /* end provided path */ + } - efree(pathbuf); return NULL; +#endif /* PHP 5.2 */ } /* }}} */ -- 2.50.1