From 0262e844c4c18a9d1b6574df444b3f6adb5f835a Mon Sep 17 00:00:00 2001 From: Greg Beaver Date: Wed, 12 Mar 2008 03:55:12 +0000 Subject: [PATCH] implement full support and usage of phar stream in include_path, for both 5.2 and 5.3. 5.3 code expects the proposed patch for stream wrapper in include_path to be committed 5.2 code only supports phar stream wrapper in include_path. this is a 2-step process. After this, more magic, particularly in funcinterceptors.c will be converted to use phar_resolve_path, which is far safer than the current implementation. this needs windows and 5.2 testing unix/windows --- ext/phar/func_interceptors.c | 7 +- ext/phar/phar.c | 292 +++++++++++++++++++- ext/phar/phar_internal.h | 2 +- ext/phar/shortarc.php | 1 + ext/phar/stream.c | 6 + ext/phar/stub.h | 6 +- ext/phar/tests/files/frontcontroller13.phar | Bin 330 -> 330 bytes ext/phar/tests/files/nophar.phar | Bin 6965 -> 7017 bytes ext/phar/tests/include_path.phpt | 34 +++ ext/phar/tests/phar_commitwrite.phpt | 2 +- ext/phar/tests/phar_convert_repeated.phpt | 2 +- ext/phar/tests/phar_convert_repeated_b.phpt | 4 +- ext/phar/tests/phar_create_in_cwd.phpt | 2 +- ext/phar/tests/phar_createdefaultstub.phpt | 19 +- ext/phar/tests/phar_magic.phpt | 1 + ext/phar/tests/phar_setdefaultstub.phpt | 17 +- ext/phar/tests/tar/phar_convert_phar.phpt | 6 +- ext/phar/tests/tar/phar_convert_phar2.phpt | 6 +- ext/phar/tests/tar/phar_convert_phar3.phpt | 6 +- ext/phar/tests/tar/phar_magic.phpt | 1 + ext/phar/tests/tempmanifest1.phpt | 34 --- ext/phar/tests/zip/phar_convert_phar.phpt | 6 +- ext/phar/tests/zip/phar_magic.phpt | 1 + ext/phar/util.c | 63 ++++- 24 files changed, 436 insertions(+), 82 deletions(-) create mode 100644 ext/phar/tests/include_path.phpt delete mode 100644 ext/phar/tests/tempmanifest1.phpt diff --git a/ext/phar/func_interceptors.c b/ext/phar/func_interceptors.c index ed52cb062c..b611427932 100644 --- a/ext/phar/func_interceptors.c +++ b/ext/phar/func_interceptors.c @@ -136,7 +136,7 @@ PHAR_FUNC(phar_file_get_contents) /* {{{ */ 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, old, *pphar TSRMLS_CC))) { + if (!(entry = phar_find_in_include_path(entry, pphar TSRMLS_CC))) { /* this file is not in the phar, use the original path */ efree(arch); efree(old); @@ -243,13 +243,15 @@ 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, old, *pphar TSRMLS_CC))) { + if (!(entry = phar_find_in_include_path(entry, pphar TSRMLS_CC))) { /* this file is not in the phar, use the original path */ efree(old); efree(arch); goto skip_phar; } efree(old); + name = entry; + goto already_setup; } else { efree(old); entry = phar_fix_filepath(entry, &entry_len, 1 TSRMLS_CC); @@ -266,6 +268,7 @@ PHAR_FUNC(phar_fopen) /* {{{ */ if (entry != filename) { efree(entry); } +already_setup: efree(arch); context = php_stream_context_from_zval(zcontext, 0); stream = php_stream_open_wrapper_ex(name, mode, 0 | REPORT_ERRORS, NULL, context); diff --git a/ext/phar/phar.c b/ext/phar/phar.c index b02a693106..9217eeeb08 100644 --- a/ext/phar/phar.c +++ b/ext/phar/phar.c @@ -2567,7 +2567,244 @@ 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 + +/* + Used to add the fake CWD to include_path prior to parsing it in PHP 5.3+ + Does complete include_path scan for file in PHP 5.2 + + This is only called in PHP 5.2 if we know for certain that we are running within + a phar, and only supports phar stream wrapper in 5.2. + */ +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); + 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 */ +} static zend_op_array *phar_compile_file(zend_file_handle *file_handle, int type TSRMLS_DC) /* {{{ */ { @@ -2587,6 +2824,9 @@ static zend_op_array *phar_compile_file(zend_file_handle *file_handle, int type efree(name); name = NULL; file_handle->filename = f.filename; + if (file_handle->opened_path) { + efree(file_handle->opened_path); + } file_handle->opened_path = f.opened_path; file_handle->free_filename = f.free_filename; } else { @@ -2624,13 +2864,45 @@ skip_phar: } /* }}} */ +#if PHP_VERSION_ID < 50300 int phar_zend_open(const char *filename, zend_file_handle *handle TSRMLS_DC) /* {{{ */ { char *arch, *entry; + int arch_len, entry_len; + /* this code is obsoleted in php 5.3 */ entry = (char *) filename; - if (zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map))) { - int arch_len, entry_len; + if (!IS_ABSOLUTE_PATH(entry, strlen(entry))) { + phar_archive_data **pphar = NULL; + char *fname; + int fname_len; + + fname = zend_get_executed_filename(TSRMLS_C); + fname_len = strlen(fname); + if (fname_len > 7 && !strncasecmp(fname, "phar://", 7)) { + if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len TSRMLS_CC)) { + zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **) &pphar); + efree(arch); + efree(entry); + } + } + /* retrieving an include within the current directory, so use this if possible */ + if (!(entry = phar_find_in_include_path((char *) filename, pphar TSRMLS_CC))) { + /* this file is not in the phar, use the original path */ + goto skip_phar; + } + if (SUCCESS == phar_orig_zend_open(entry, handle TSRMLS_CC)) { + if (!handle->opened_path) { + handle->opened_path = entry; + } + return SUCCESS; + } + if (entry != filename) { + efree(entry); + } + return FAILURE; + } + if (0 && zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map))) { char *fname = NULL; int fname_len; @@ -2655,7 +2927,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, old, *pphar TSRMLS_CC))) { + if (!(entry = phar_find_in_include_path(entry, 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)) { @@ -2693,6 +2965,7 @@ skip_phar: return phar_orig_zend_open(filename, handle TSRMLS_CC); } /* }}} */ +#endif PHP_MINIT_FUNCTION(phar) /* {{{ */ { @@ -2702,11 +2975,16 @@ PHP_MINIT_FUNCTION(phar) /* {{{ */ phar_has_bz2 = zend_hash_exists(&module_registry, "bz2", sizeof("bz2")); phar_has_zlib = zend_hash_exists(&module_registry, "zlib", sizeof("zlib")); - phar_orig_compile_file = zend_compile_file; - zend_compile_file = phar_compile_file; - +#if PHP_VERSION_ID >= 50300 + phar_save_resolve_path = zend_resolve_path; + zend_resolve_path = phar_resolve_path; +#else phar_orig_zend_open = zend_stream_open_function; zend_stream_open_function = phar_zend_open; +#endif + + phar_orig_compile_file = zend_compile_file; + zend_compile_file = phar_compile_file; phar_object_init(TSRMLS_C); @@ -2720,9 +2998,11 @@ PHP_MSHUTDOWN_FUNCTION(phar) /* {{{ */ if (zend_compile_file == phar_compile_file) { zend_compile_file = phar_orig_compile_file; } +#if PHP_VERSION_ID < 50300 if (zend_stream_open_function == phar_zend_open) { zend_stream_open_function = phar_orig_zend_open; } +#endif } /* }}} */ diff --git a/ext/phar/phar_internal.h b/ext/phar/phar_internal.h index 0eac89ee35..68963ebe30 100755 --- a/ext/phar/phar_internal.h +++ b/ext/phar/phar_internal.h @@ -378,7 +378,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, char *entry, phar_archive_data *phar TSRMLS_DC); +char *phar_find_in_include_path(char *file, phar_archive_data **phar 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/shortarc.php b/ext/phar/shortarc.php index 5c73e53d01..fa52636646 100644 --- a/ext/phar/shortarc.php +++ b/ext/phar/shortarc.php @@ -4,6 +4,7 @@ $web = '000'; if (in_array('phar', stream_get_wrappers()) && class_exists('Phar', 0)) { Phar::interceptFileFuncs(); + set_include_path('phar://' . __FILE__ . PATH_SEPARATOR . get_include_path()); Phar::webPhar(null, $web); include 'phar://' . __FILE__ . '/' . Extract_Phar::START; return; diff --git a/ext/phar/stream.c b/ext/phar/stream.c index 210dc656fc..993304a270 100644 --- a/ext/phar/stream.c +++ b/ext/phar/stream.c @@ -235,6 +235,9 @@ static php_stream * phar_wrapper_open_url(php_stream_wrapper *wrapper, char *pat idata->phar->is_modified = 1; } } + if (opened_path) { + spprintf(opened_path, MAXPATHLEN, "phar://%s/%s", idata->phar->fname, idata->internal_file->filename); + } return fpf; } else { if ((FAILURE == phar_get_entry_data(&idata, resource->host, host_len, internal_file, strlen(internal_file), "r", 0, &error TSRMLS_CC)) || !idata) { @@ -286,6 +289,9 @@ static php_stream * phar_wrapper_open_url(php_stream_wrapper *wrapper, char *pat } } fpf = php_stream_alloc(&phar_ops, idata, NULL, mode); + if (opened_path) { + spprintf(opened_path, MAXPATHLEN, "phar://%s/%s", idata->phar->fname, idata->internal_file->filename); + } efree(internal_file); return fpf; } diff --git a/ext/phar/stub.h b/ext/phar/stub.h index d019f71007..f5858e2f07 100644 --- a/ext/phar/stub.h +++ b/ext/phar/stub.h @@ -21,13 +21,13 @@ static inline void phar_get_stub(const char *index_php, const char *web, size_t *len, char **stub, const int name_len, const int web_len TSRMLS_DC) { static const char newstub0[] = " 2,\n'c' => 'text/plain',\n'cc' => 'text/plain',\n'cpp' => 'text/plain',\n'c++' => 'text/plain',\n'dtd' => 'text/plain',\n'h' => 'text/plain',\n'log' => 'text/plain',\n'rng' => 'text/plain',\n'txt' => 'text/plain',\n'xsd' => 'text/plain',\n'php' => 1,\n'inc' => 1,\n'avi' => 'video/avi',\n'bmp' => 'image/bmp',\n'css' => 'text/css',\n'gif' => 'image/gif',\n'htm' => 'text/html',\n'html' => 'text/html',\n'htmls' => 'text/html',\n'ico' => 'image/x-ico',\n'jpe' => 'image/jpeg',\n'jpg' => 'image/jpeg',\n'jpeg' => 'image/jpeg',\n'js' => 'application/x-javascript',\n'midi' => 'audio/midi',\n'mid' => 'audio/midi',\n'mod' => 'audio/mod',\n'mov' => 'movie/quicktime',\n'mp3' => 'audio/mp3',\n'mpg' => 'video/mpeg',\n'mpeg' => 'video/mpeg',\n'pdf' => 'application/pdf',\n'png' => 'image/png',\n'swf' => 'application/shockwave-flash',\n'tif' => 'image/tiff',\n'tiff' => 'image/tiff',\n'wav' => 'audio/wav',\n'xbm' => 'image/xbm',\n'xml' => 'text/xml',\n);\n\nheader(\"Cache-Control: no-cache, must-revalidate\");\nheader(\"Pragma: no-cache\");\n\n$basename = basename(__FILE__);\nif (!strpos($_SERVER['REQUEST_URI'], $basename)) {\nchdir(Extract_Phar::$temp);\ninclude $web;\nreturn;\n}\n$pt = substr($_SERVER['REQUEST_URI'], strpos($_SERVER['REQUEST_URI'], $basename) + strlen($basename));\nif (!$pt || $pt == '/') {\n$pt = $web;\nheader('HTTP/1.1 301 Moved Permanently');\nheader('Location: ' . $_SERVER['REQUEST_URI'] . '/' . $pt);\nexit;\n}\n$a = realpath(Extract_Phar::$temp . DIRECTORY_SEPARATOR . $pt);\nif (!$a || strlen(dirname($a)) < strlen(Extract_Phar::$temp)) {\nheader('HTTP/1.0 404 Not Found');\necho \"\\n \\n \\n\";\nexit;\n}\n$b = pathinfo($a);\nif (!isset($b['extension'])) {\nheader('Content-Type: text/plain');\nheader('Content-Length: ' . filesize($a));\nreadfile($a);\nexit;\n}\nif (isset($mimes[$b['extension']])) {\nif ($mimes[$b['extension']] === 1) {\ninclude $a;\nexit;\n}\nif ($mimes[$b['extension']] === 2) {\nhighlight_file($a);\nexit;\n}\nheader('Content-Type: ' .$mimes[$b['extension']]);\nheader('Content-Length: ' . filesize($a));\nreadfile($a);\nexit;\n}\n}\n\nclass Extract_Phar\n{\nstatic $temp;\nstatic $origdir;\nconst GZ = 0x1000;\nconst BZ2 = 0x2000;\nconst MASK = 0x3000;\nconst START = '"; + static const char newstub1_0[] = "';\n\nif (in_array('phar', stream_get_wrappers()) && class_exists('Phar', 0)) {\nPhar::interceptFileFuncs();\nset_include_path('phar://' . __FILE__ . PATH_SEPARATOR . get_include_path());\nPhar::webPhar(null, $web);\ninclude 'phar://' . __FILE__ . '/' . Extract_Phar::START;\nreturn;\n}\n\nif (@(isset($_SERVER['REQUEST_URI']) && isset($_SERVER['REQUEST_METHOD']) && ($_SERVER['REQUEST_METHOD'] == 'GET' || $_SERVER['REQUEST_METHOD'] == 'POST'))) {\nExtract_Phar::go(true);\n$mimes = array(\n'phps' => 2,\n'c' => 'text/plain',\n'cc' => 'text/plain',\n'cpp' => 'text/plain',\n'c++' => 'text/plain',\n'dtd' => 'text/plain',\n'h' => 'text/plain',\n'log' => 'text/plain',\n'rng' => 'text/plain',\n'txt' => 'text/plain',\n'xsd' => 'text/plain',\n'php' => 1,\n'inc' => 1,\n'avi' => 'video/avi',\n'bmp' => 'image/bmp',\n'css' => 'text/css',\n'gif' => 'image/gif',\n'htm' => 'text/html',\n'html' => 'text/html',\n'htmls' => 'text/html',\n'ico' => 'image/x-ico',\n'jpe' => 'image/jpeg',\n'jpg' => 'image/jpeg',\n'jpeg' => 'image/jpeg',\n'js' => 'application/x-javascript',\n'midi' => 'audio/midi',\n'mid' => 'audio/midi',\n'mod' => 'audio/mod',\n'mov' => 'movie/quicktime',\n'mp3' => 'audio/mp3',\n'mpg' => 'video/mpeg',\n'mpeg' => 'video/mpeg',\n'pdf' => 'application/pdf',\n'png' => 'image/png',\n'swf' => 'application/shockwave-flash',\n'tif' => 'image/tiff',\n'tiff' => 'image/tiff',\n'wav' => 'audio/wav',\n'xbm' => 'image/xbm',\n'xml' => 'text/xml',\n);\n\nheader(\"Cache-Control: no-cache, must-revalidate\");\nheader(\"Pragma: no-cache\");\n\n$basename = basename(__FILE__);\nif (!strpos($_SERVER['REQUEST_URI'], $basename)) {\nchdir(Extract_Phar::$temp);\ninclude $web;\nreturn;\n}\n$pt = substr($_SERVER['REQUEST_URI'], strpos($_SERVER['REQUEST_URI'], $basename) + strlen($basename));\nif (!$pt || $pt == '/') {\n$pt = $web;\nheader('HTTP/1.1 301 Moved Permanently');\nheader('Location: ' . $_SERVER['REQUEST_URI'] . '/' . $pt);\nexit;\n}\n$a = realpath(Extract_Phar::$temp . DIRECTORY_SEPARATOR . $pt);\nif (!$a || strlen(dirname($a)) < strlen("; + static const char newstub1_1[] = "Extract_Phar::$temp)) {\nheader('HTTP/1.0 404 Not Found');\necho \"\\n \\n File Not Found<title>\\n </head>\\n <body>\\n <h1>404 - File \", $pt, \" Not Found</h1>\\n </body>\\n</html>\";\nexit;\n}\n$b = pathinfo($a);\nif (!isset($b['extension'])) {\nheader('Content-Type: text/plain');\nheader('Content-Length: ' . filesize($a));\nreadfile($a);\nexit;\n}\nif (isset($mimes[$b['extension']])) {\nif ($mimes[$b['extension']] === 1) {\ninclude $a;\nexit;\n}\nif ($mimes[$b['extension']] === 2) {\nhighlight_file($a);\nexit;\n}\nheader('Content-Type: ' .$mimes[$b['extension']]);\nheader('Content-Length: ' . filesize($a));\nreadfile($a);\nexit;\n}\n}\n\nclass Extract_Phar\n{\nstatic $temp;\nstatic $origdir;\nconst GZ = 0x1000;\nconst BZ2 = 0x2000;\nconst MASK = 0x3000;\nconst START = '"; static const char newstub2[] = "';\nconst LEN = "; static const char newstub3_0[] = ";\n\nstatic function go($return = false)\n{\n$fp = fopen(__FILE__, 'rb');\nfseek($fp, self::LEN);\n$L = unpack('V', $a = fread($fp, 4));\n$m = '';\n\ndo {\n$read = 8192;\nif ($L[1] - strlen($m) < 8192) {\n$read = $L[1] - strlen($m);\n}\n$last = fread($fp, $read);\n$m .= $last;\n} while (strlen($last) && strlen($m) < $L[1]);\n\nif (strlen($m) < $L[1]) {\ndie('ERROR: manifest length read was \"' .\nstrlen($m) .'\" should be \"' .\n$L[1] . '\"');\n}\n\n$info = self::_unpack($m);\n$f = $info['c'];\n\nif ($f & self::GZ) {\nif (!function_exists('gzinflate')) {\ndie('Error: zlib extension is not enabled -' .\n' gzinflate() function needed for zlib-compressed .phars');\n}\n}\n\nif ($f & self::BZ2) {\nif (!function_exists('bzdecompress')) {\ndie('Error: bzip2 extension is not enabled -' .\n' bzdecompress() function needed for bz2-compressed .phars');\n}\n}\n\n$temp = self::tmpdir();\n\nif (!$temp || !is_writable($temp)) {\n$sessionpath = session_save_path();\nif (strpos ($sessionpath, \";\") !== false)\n$sessionpath = substr ($sessionpath, strpos ($sessionpath, \";\")+1);\nif (!file_exists($sessionpath) || !is_dir($sessionpath)) {\ndie('Could not locate temporary directory to extract phar');\n}\n$temp = $sessionpath;\n}\n\n$temp .= '/pharextract/'.basename(__FILE__, '.phar');\nself::$temp = $temp;\nself::$origdir = getcwd();\n@mkdir($temp, 0777, true);\n$temp = realpath($temp);\n\nif (!file_exists($temp . DIRECTORY_SEPARATOR . md5_file(__FILE__))) {\nself::_removeTmpFiles($temp, getcwd());\n@mkdir($temp, 0777, true);\n@file_put_contents($temp . '/' . md5_file(__FILE__), '');\n\nforeach ($info['m'] as $path => $file) {\n$a = !file_exists(dirname($temp . '/' . $path));\n@mkdir(dirname($temp . '/' . $path), 0777, true);\nclearstatcache();\n\nif ($path[strlen($path) - 1] == '/') {\n@mkdir($temp . '/' . $path, 0777);\n} else {\nfile_put_contents($temp . '/' . $path, self::extractFile($path, $file, $fp));\n@chmod($temp . '/' . $path, 0666);\n}\n}\n}\n\nchdir($temp);\n\nif (!$return) {\ninclude self::START;\n}\n}\n\nstatic fun"; static const char newstub3_1[] = "ction tmpdir()\n{\nif (strpos(PHP_OS, 'WIN') !== false) {\nif ($var = getenv('TMP') ? getenv('TMP') : getenv('TEMP')) {\nreturn $var;\n}\nif (is_dir('/temp') || mkdir('/temp')) {\nreturn realpath('/temp');\n}\nreturn false;\n}\nif ($var = getenv('TMPDIR')) {\nreturn $var;\n}\nreturn realpath('/tmp');\n}\n\nstatic function _unpack($m)\n{\n$info = unpack('V', substr($m, 0, 4));\n $l = unpack('V', substr($m, 10, 4));\n$m = substr($m, 14 + $l[1]);\n$s = unpack('V', substr($m, 0, 4));\n$o = 0;\n$start = 4 + $s[1];\n$ret['c'] = 0;\n\nfor ($i = 0; $i < $info[1]; $i++) {\n $len = unpack('V', substr($m, $start, 4));\n$start += 4;\n $savepath = substr($m, $start, $len[1]);\n$start += $len[1];\n $ret['m'][$savepath] = array_values(unpack('Va/Vb/Vc/Vd/Ve/Vf', substr($m, $start, 24)));\n$ret['m'][$savepath][3] = sprintf('%u', $ret['m'][$savepath][3]\n& 0xffffffff);\n$ret['m'][$savepath][7] = $o;\n$o += $ret['m'][$savepath][2];\n$start += 24 + $ret['m'][$savepath][5];\n$ret['c'] |= $ret['m'][$savepath][4] & self::MASK;\n}\nreturn $ret;\n}\n\nstatic function extractFile($path, $entry, $fp)\n{\n$data = '';\n$c = $entry[2];\n\nwhile ($c) {\nif ($c < 8192) {\n$data .= @fread($fp, $c);\n$c = 0;\n} else {\n$c -= 8192;\n$data .= @fread($fp, 8192);\n}\n}\n\nif ($entry[4] & self::GZ) {\n$data = gzinflate($data);\n} elseif ($entry[4] & self::BZ2) {\n$data = bzdecompress($data);\n}\n\nif (strlen($data) != $entry[0]) {\ndie(\"Invalid internal .phar file (size error \" . strlen($data) . \" != \" .\n$stat[7] . \")\");\n}\n\nif ($entry[3] != sprintf(\"%u\", crc32($data) & 0xffffffff)) {\ndie(\"Invalid internal .phar file (checksum error)\");\n}\n\nreturn $data;\n}\n\nstatic function _removeTmpFiles($temp, $origdir)\n{\nchdir($temp);\n\nforeach (glob('*') as $f) {\nif (file_exists($f)) {\nis_dir($f) ? @rmdir($f) : @unlink($f);\nif (file_exists($f) && is_dir($f)) {\nself::_removeTmpFiles($f, getcwd());\n}\n}\n}\n\n@rmdir($temp);\nclearstatcache();\nchdir($origdir);\n}\n}\n\nExtract_Phar::go();\n__HALT_COMPILER(); ?>"; - static const int newstub_len = 6555; + static const int newstub_len = 6633; *len = spprintf(stub, name_len + web_len + newstub_len, "%s%s%s%s%s%s%d%s%s", newstub0, web, newstub1_0, newstub1_1, index_php, newstub2, name_len + web_len + newstub_len, newstub3_0, newstub3_1); } diff --git a/ext/phar/tests/files/frontcontroller13.phar b/ext/phar/tests/files/frontcontroller13.phar index 2434b1e32d9e15fbd233b582d9ab79fb70773baf..750ff27a8e339abd0ac0fab5537716590321049f 100644 GIT binary patch delta 56 zcmX@bbc$(0DDzdH>k}hX!Bm4Xm|E5$qxj&k^%M4WORN@MIJ9b6Y_*r}>+MVo3=Hm0 GzD@w!^B9o; delta 56 zcmX@bbc$(0D6@BP>%<6EFx8+8rj~WcEH7`K_CE2|G2O?@46kkUyC1nw`y3Mk1B1Jh GuM+@?+!pKr diff --git a/ext/phar/tests/files/nophar.phar b/ext/phar/tests/files/nophar.phar index 3672e4f26280d0a3dda637b4033252577a01c7fd..ae04a15ef6e79ddc0a87dd5990111a3c34419383 100644 GIT binary patch delta 184 zcmdmL_R?%ZgJ5xLNqlBra!zSVYJ5RrNruM6jpC{Sjv*fL!L9+0L5?B*K?-^b>FBC7 zHLWLh%S>G9Iq{z-qsHVsM)}EUjCz|VGnR8q=HZ&jY-Vb>c?FjnKl7pT%acD!Du8Jb zDFp=}-@TcEfx+DPTK_giAOi?MR0=DQ04WZUIx53Bf8KJ|wSVm$t6Qwx4|2?!|5h`D L2`KOG<m&_gj`lu) delta 125 zcmaE9w$*Gx19xVcf`&?YYLccx^~AF>jI|SAc(FtIlXV&WCL6H}P3~i~-h7I&jAODL z*KB4}OUuo7xZL=eCD`UqR+Ul!(;iSdTS^Md?~pnwv(C8w-_r&rIh`iqS(lA&%0+f1 O%wS?*U~qTxbpik$11KE; diff --git a/ext/phar/tests/include_path.phpt b/ext/phar/tests/include_path.phpt new file mode 100644 index 0000000000..a0c753ccc6 --- /dev/null +++ b/ext/phar/tests/include_path.phpt @@ -0,0 +1,34 @@ +--TEST-- +Phar: include_path with phar:// wrapper +--SKIPIF-- +<?php if (!extension_loaded("phar")) die("skip"); ?> +--INI-- +phar.readonly=0 +--FILE-- +<?php +$fname = dirname(__FILE__) . '/tempmanifest1.phar.php'; +$a = new Phar($fname); +$a['file1.php'] = 'file1.php +'; +$a['test/file1.php'] = 'test/file1.php +'; +unset($a); +set_include_path('.' . PATH_SEPARATOR . 'phar://' . $fname); +include 'file1.php'; +set_include_path('.' . PATH_SEPARATOR . 'phar://' . $fname . '/test'); +include 'file1.php'; +include 'file2.php'; +?> +===DONE=== +--CLEAN-- +<?php +@unlink(dirname(__FILE__) . '/tempmanifest1.phar.php'); +?> +--EXPECTF-- +file1.php +test/file1.php + +Warning: include(file2.php): failed to open stream: No such file or directory in %sinclude_path.php on line %d + +Warning: include(): Failed opening 'file2.php' for inclusion (include_path='.:phar:///home/cellog/workspace/php5/ext/phar/tests/tempmanifest1.phar.php/test') in %sinclude_path.php on line %d +===DONE=== \ No newline at end of file diff --git a/ext/phar/tests/phar_commitwrite.phpt b/ext/phar/tests/phar_commitwrite.phpt index 2693f0262f..63878355b0 100644 --- a/ext/phar/tests/phar_commitwrite.phpt +++ b/ext/phar/tests/phar_commitwrite.phpt @@ -29,7 +29,7 @@ unlink(dirname(__FILE__) . '/brandnewphar.phar'); __HALT_COMPILER(); ?> --EXPECT-- -int(6573) +int(6651) string(200) "<?php function __autoload($class) { diff --git a/ext/phar/tests/phar_convert_repeated.phpt b/ext/phar/tests/phar_convert_repeated.phpt index 0e3c8d9792..480d7900c7 100644 --- a/ext/phar/tests/phar_convert_repeated.phpt +++ b/ext/phar/tests/phar_convert_repeated.phpt @@ -115,7 +115,7 @@ string(%d) "%sphar_convert_repeated.phar.zip" bool(true) bool(false) bool(false) -int(6573) +int(6651) string(%d) "%sphar_convert_repeated.phar" ================= convertToZip() ===================== bool(false) diff --git a/ext/phar/tests/phar_convert_repeated_b.phpt b/ext/phar/tests/phar_convert_repeated_b.phpt index 28884662b3..9e5b403cc9 100644 --- a/ext/phar/tests/phar_convert_repeated_b.phpt +++ b/ext/phar/tests/phar_convert_repeated_b.phpt @@ -104,7 +104,7 @@ NULL bool(true) bool(false) bool(false) -int(6573) +int(6651) NULL ================ convertToTar(GZ) ==================== bool(false) @@ -116,6 +116,6 @@ NULL bool(true) bool(false) bool(false) -int(6573) +int(6651) NULL ===DONE=== diff --git a/ext/phar/tests/phar_create_in_cwd.phpt b/ext/phar/tests/phar_create_in_cwd.phpt index 206a92a15f..83de7bed28 100644 --- a/ext/phar/tests/phar_create_in_cwd.phpt +++ b/ext/phar/tests/phar_create_in_cwd.phpt @@ -32,7 +32,7 @@ __HALT_COMPILER(); unlink(dirname(__FILE__) . '/brandnewphar.phar'); ?> --EXPECT-- -int(6573) +int(6651) string(200) "<?php function __autoload($class) { diff --git a/ext/phar/tests/phar_createdefaultstub.phpt b/ext/phar/tests/phar_createdefaultstub.phpt index 6569b14d46..a8648dc311 100644 --- a/ext/phar/tests/phar_createdefaultstub.phpt +++ b/ext/phar/tests/phar_createdefaultstub.phpt @@ -34,12 +34,13 @@ echo $e->getMessage() . "\n"; ?> ===DONE=== --EXPECT-- -string(6573) "<?php +string(6651) "<?php $web = 'index.php'; if (in_array('phar', stream_get_wrappers()) && class_exists('Phar', 0)) { Phar::interceptFileFuncs(); +set_include_path('phar://' . __FILE__ . PATH_SEPARATOR . get_include_path()); Phar::webPhar(null, $web); include 'phar://' . __FILE__ . '/' . Extract_Phar::START; return; @@ -143,7 +144,7 @@ const GZ = 0x1000; const BZ2 = 0x2000; const MASK = 0x3000; const START = 'index.php'; -const LEN = 6575; +const LEN = 6653; static function go($return = false) { @@ -327,12 +328,13 @@ Extract_Phar::go(); __HALT_COMPILER(); ?>" ============================================================================ ============================================================================ -string(6584) "<?php +string(6662) "<?php $web = 'index.php'; if (in_array('phar', stream_get_wrappers()) && class_exists('Phar', 0)) { Phar::interceptFileFuncs(); +set_include_path('phar://' . __FILE__ . PATH_SEPARATOR . get_include_path()); Phar::webPhar(null, $web); include 'phar://' . __FILE__ . '/' . Extract_Phar::START; return; @@ -436,7 +438,7 @@ const GZ = 0x1000; const BZ2 = 0x2000; const MASK = 0x3000; const START = 'my/custom/thingy.php'; -const LEN = 6586; +const LEN = 6664; static function go($return = false) { @@ -620,7 +622,7 @@ Extract_Phar::go(); __HALT_COMPILER(); ?>" ============================================================================ ============================================================================ -int(6964) +int(7042) ============================================================================ ============================================================================ Illegal filename passed in for stub creation, was 401 characters long, and only 400 or less is allowed @@ -628,12 +630,13 @@ Illegal filename passed in for stub creation, was 401 characters long, and only ============================================================================ ============================================================================ ============================================================================ -string(6586) "<?php +string(6664) "<?php $web = 'the/web.php'; if (in_array('phar', stream_get_wrappers()) && class_exists('Phar', 0)) { Phar::interceptFileFuncs(); +set_include_path('phar://' . __FILE__ . PATH_SEPARATOR . get_include_path()); Phar::webPhar(null, $web); include 'phar://' . __FILE__ . '/' . Extract_Phar::START; return; @@ -737,7 +740,7 @@ const GZ = 0x1000; const BZ2 = 0x2000; const MASK = 0x3000; const START = 'my/custom/thingy.php'; -const LEN = 6588; +const LEN = 6666; static function go($return = false) { @@ -921,6 +924,6 @@ Extract_Phar::go(); __HALT_COMPILER(); ?>" ============================================================================ ============================================================================ -int(6964) +int(7042) Illegal web filename passed in for stub creation, was 401 characters long, and only 400 or less is allowed ===DONE=== diff --git a/ext/phar/tests/phar_magic.phpt b/ext/phar/tests/phar_magic.phpt index 341a36046a..f6a0a675ef 100644 --- a/ext/phar/tests/phar_magic.phpt +++ b/ext/phar/tests/phar_magic.phpt @@ -13,6 +13,7 @@ $p['a'] = '<?php include "b/c.php";' . "\n"; $p['b/c.php'] = '<?php echo "in b\n";$a = fopen("a", "r", true);echo stream_get_contents($a);fclose($a);include dirname(__FILE__) . "/../d";'; $p['d'] = "in d\n"; $p->setStub('<?php +set_include_path("phar://" . __FILE__); include "phar://" . __FILE__ . "/a"; __HALT_COMPILER();'); include $fname; diff --git a/ext/phar/tests/phar_setdefaultstub.phpt b/ext/phar/tests/phar_setdefaultstub.phpt index 7e209098e2..a36c005eac 100644 --- a/ext/phar/tests/phar_setdefaultstub.phpt +++ b/ext/phar/tests/phar_setdefaultstub.phpt @@ -54,12 +54,13 @@ try { unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar'); ?> --EXPECT-- -string(6575) "<?php +string(6653) "<?php $web = 'index.php'; if (in_array('phar', stream_get_wrappers()) && class_exists('Phar', 0)) { Phar::interceptFileFuncs(); +set_include_path('phar://' . __FILE__ . PATH_SEPARATOR . get_include_path()); Phar::webPhar(null, $web); include 'phar://' . __FILE__ . '/' . Extract_Phar::START; return; @@ -163,7 +164,7 @@ const GZ = 0x1000; const BZ2 = 0x2000; const MASK = 0x3000; const START = 'index.php'; -const LEN = 6575; +const LEN = 6653; static function go($return = false) { @@ -348,12 +349,13 @@ __HALT_COMPILER(); ?> " ============================================================================ ============================================================================ -string(6586) "<?php +string(6664) "<?php $web = 'index.php'; if (in_array('phar', stream_get_wrappers()) && class_exists('Phar', 0)) { Phar::interceptFileFuncs(); +set_include_path('phar://' . __FILE__ . PATH_SEPARATOR . get_include_path()); Phar::webPhar(null, $web); include 'phar://' . __FILE__ . '/' . Extract_Phar::START; return; @@ -457,7 +459,7 @@ const GZ = 0x1000; const BZ2 = 0x2000; const MASK = 0x3000; const START = 'my/custom/thingy.php'; -const LEN = 6586; +const LEN = 6664; static function go($return = false) { @@ -642,12 +644,13 @@ __HALT_COMPILER(); ?> " ============================================================================ ============================================================================ -string(6588) "<?php +string(6666) "<?php $web = 'the/web.php'; if (in_array('phar', stream_get_wrappers()) && class_exists('Phar', 0)) { Phar::interceptFileFuncs(); +set_include_path('phar://' . __FILE__ . PATH_SEPARATOR . get_include_path()); Phar::webPhar(null, $web); include 'phar://' . __FILE__ . '/' . Extract_Phar::START; return; @@ -751,7 +754,7 @@ const GZ = 0x1000; const BZ2 = 0x2000; const MASK = 0x3000; const START = 'my/custom/thingy.php'; -const LEN = 6588; +const LEN = 6666; static function go($return = false) { @@ -936,6 +939,6 @@ __HALT_COMPILER(); ?> " ============================================================================ ============================================================================ -int(6966) +int(7044) Illegal filename passed in for stub creation, was 401 characters long, and only 400 or less is allowed ===DONE=== diff --git a/ext/phar/tests/tar/phar_convert_phar.phpt b/ext/phar/tests/tar/phar_convert_phar.phpt index 92e755bd30..9697329f1b 100644 --- a/ext/phar/tests/tar/phar_convert_phar.phpt +++ b/ext/phar/tests/tar/phar_convert_phar.phpt @@ -42,12 +42,12 @@ __HALT_COMPILER(); ?> --EXPECT-- bool(false) -int(6573) +int(6651) bool(true) string(60) "<?php // tar-based phar archive stub file __HALT_COMPILER();" bool(true) -int(6573) +int(6651) bool(true) -int(6573) +int(6651) ===DONE=== diff --git a/ext/phar/tests/tar/phar_convert_phar2.phpt b/ext/phar/tests/tar/phar_convert_phar2.phpt index 898accc98c..4bfda39069 100644 --- a/ext/phar/tests/tar/phar_convert_phar2.phpt +++ b/ext/phar/tests/tar/phar_convert_phar2.phpt @@ -45,14 +45,14 @@ __HALT_COMPILER(); ?> --EXPECT-- bool(false) -int(6573) +int(6651) bool(true) string(60) "<?php // tar-based phar archive stub file __HALT_COMPILER();" bool(true) int(4096) -int(6573) +int(6651) bool(true) bool(true) -int(6573) +int(6651) ===DONE=== diff --git a/ext/phar/tests/tar/phar_convert_phar3.phpt b/ext/phar/tests/tar/phar_convert_phar3.phpt index 3d3b80e9d4..b8b3104a08 100644 --- a/ext/phar/tests/tar/phar_convert_phar3.phpt +++ b/ext/phar/tests/tar/phar_convert_phar3.phpt @@ -45,14 +45,14 @@ __HALT_COMPILER(); ?> --EXPECT-- bool(false) -int(6573) +int(6651) bool(true) string(60) "<?php // tar-based phar archive stub file __HALT_COMPILER();" bool(true) int(8192) -int(6573) +int(6651) bool(true) bool(true) -int(6573) +int(6651) ===DONE=== diff --git a/ext/phar/tests/tar/phar_magic.phpt b/ext/phar/tests/tar/phar_magic.phpt index e2da21634f..6af907174d 100644 --- a/ext/phar/tests/tar/phar_magic.phpt +++ b/ext/phar/tests/tar/phar_magic.phpt @@ -14,6 +14,7 @@ $p['a'] = '<?php include "b/c.php";' . "\n"; $p['b/c.php'] = '<?php echo "in b\n";$a = fopen("a", "r", true);echo stream_get_contents($a);fclose($a);include dirname(__FILE__) . "/../d";'; $p['d'] = "in d\n"; $p->setStub('<?php +set_include_path("phar://" . __FILE__); include "phar://" . __FILE__ . "/a"; __HALT_COMPILER();'); include $fname; diff --git a/ext/phar/tests/tempmanifest1.phpt b/ext/phar/tests/tempmanifest1.phpt deleted file mode 100644 index bff1026b1c..0000000000 --- a/ext/phar/tests/tempmanifest1.phpt +++ /dev/null @@ -1,34 +0,0 @@ ---TEST-- -Phar: temporary manifest entry test ---SKIPIF-- -<?php if (!extension_loaded("phar")) die("skip"); ?> ---INI-- -phar.readonly=0 ---FILE-- -<?php -$fname = dirname(__FILE__) . '/tempmanifest1.phar.php'; -$a = new Phar($fname); -$a['index.php'] = '<?php -set_include_path("' . addslashes(dirname(__FILE__)) . '"); -include "extfile.php"; -?>'; -$a->setStub('<?php -include "phar://" . __FILE__ . "/index.php"; -__HALT_COMPILER();'); -unset($a); -file_put_contents(dirname(__FILE__) . '/extfile.php', '<?php -var_dump(__FILE__); -?>'); -include dirname(__FILE__) . '/extfile.php'; -include $fname; -?> -===DONE=== ---CLEAN-- -<?php -@unlink(dirname(__FILE__) . '/tempmanifest1.phar.php'); -@unlink(dirname(__FILE__) . '/extfile.php'); -?> ---EXPECTF-- -string(%d) "%sextfile.php" -string(%d) "phar://%sextfile.php" -===DONE=== \ No newline at end of file diff --git a/ext/phar/tests/zip/phar_convert_phar.phpt b/ext/phar/tests/zip/phar_convert_phar.phpt index bf596c3a02..59aad1cdc9 100644 --- a/ext/phar/tests/zip/phar_convert_phar.phpt +++ b/ext/phar/tests/zip/phar_convert_phar.phpt @@ -42,12 +42,12 @@ __HALT_COMPILER(); ?> --EXPECT-- bool(false) -int(6573) +int(6651) bool(true) string(60) "<?php // zip-based phar archive stub file __HALT_COMPILER();" bool(true) -int(6573) +int(6651) bool(true) -int(6573) +int(6651) ===DONE=== diff --git a/ext/phar/tests/zip/phar_magic.phpt b/ext/phar/tests/zip/phar_magic.phpt index 7afcc3a56c..1ac101ec75 100644 --- a/ext/phar/tests/zip/phar_magic.phpt +++ b/ext/phar/tests/zip/phar_magic.phpt @@ -14,6 +14,7 @@ $p['a'] = '<?php include "b/c.php";' . "\n"; $p['b/c.php'] = '<?php echo "in b\n";$a = fopen("a", "r", true);echo stream_get_contents($a);fclose($a);include dirname(__FILE__) . "/../d";'; $p['d'] = "in d\n"; $p->setStub('<?php +set_include_path("phar://" . __FILE__); include "phar://" . __FILE__ . "/a"; __HALT_COMPILER();'); include $fname; diff --git a/ext/phar/util.c b/ext/phar/util.c index 5fefb2406d..f965c03317 100644 --- a/ext/phar/util.c +++ b/ext/phar/util.c @@ -241,11 +241,18 @@ int phar_mount_entry(phar_archive_data *phar, char *filename, int filename_len, return FAILURE; } -char *phar_find_in_include_path(char *file, char *entry, phar_archive_data *phar TSRMLS_DC) /* {{{ */ +char *phar_find_in_include_path(char *file, phar_archive_data **pphar TSRMLS_DC) /* {{{ */ { char *path = PG(include_path), *pathbuf, *ptr, *end; char *trypath; + phar_archive_data *blank = NULL, *self; + if (!pphar) { + pphar = ␣ + self = NULL; + } else { + self = *pphar; + } if (!path || (path && !*path)) { return file; } @@ -263,6 +270,49 @@ char *phar_find_in_include_path(char *file, char *entry, phar_archive_data *phar char *test; 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; + + /* found phar:// */ + 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)) { + continue; + } + if (SUCCESS != (zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **) &pphar))) { + efree(arch); + efree(entry); + continue; + } + 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; + } + 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; + } + } + efree(test); + *pphar = self; + ptr = end; + continue; + } if (end != NULL) { *end = '\0'; end++; @@ -270,17 +320,22 @@ char *phar_find_in_include_path(char *file, char *entry, phar_archive_data *phar 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(&(phar->manifest), test + 1, try_len - 1)) { + 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 (zend_hash_num_elements(&(phar->mounted_dirs))) { - if (phar_get_entry_info_dir(phar, test + 1, try_len - 1, 0, NULL TSRMLS_CC)) { + 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); -- 2.40.0