From: Greg Beaver Date: Mon, 18 Feb 2008 04:32:50 +0000 (+0000) Subject: add Phar::mount() to manually mount a file or directory X-Git-Tag: RELEASE_2_0_0a1~445 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6798dc44ed64806011dca7974c8b0d881951eaac;p=php add Phar::mount() to manually mount a file or directory # TODO: implement directory mounting. Involves scanning paths that are not exact matches for a partial match. # this also means maintaining a per-phar hash of mounted directories for quick matching --- diff --git a/ext/phar/phar.c b/ext/phar/phar.c index d86856f9a9..46177a0a80 100644 --- a/ext/phar/phar.c +++ b/ext/phar/phar.c @@ -2568,7 +2568,7 @@ int phar_zend_open(const char *filename, zend_file_handle *handle TSRMLS_DC) /* if (!(entry = phar_find_in_include_path(entry, old, *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 (filename[0] != '.' && SUCCESS == phar_mount_entry(*pphar, handle->opened_path ? handle->opened_path : filename, strlen(handle->opened_path ? handle->opened_path : filename), filename, strlen(filename), 0)) { + 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))) { entry = (char *) filename; goto dopharthing; } diff --git a/ext/phar/phar_internal.h b/ext/phar/phar_internal.h index e256402049..5679b140f2 100755 --- a/ext/phar/phar_internal.h +++ b/ext/phar/phar_internal.h @@ -372,6 +372,7 @@ char *phar_create_default_stub(const char *index_php, const char *web_index, siz char * phar_decompress_filter(phar_entry_info * entry, int return_unknown); char * phar_compress_filter(phar_entry_info * entry, int return_unknown); +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_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, diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index 3f91ab47cb..efb2f2f57f 100755 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -414,6 +414,38 @@ static void phar_postprocess_ru_web(char *fname, int fname_len, char **entry, in } /* }}} */ +/* {{{ proto void Phar::mount(string pharpath, string externalfile) + * mount an external file or path to a location within the phar. This maps + * an external file or directory to a location within the phar archive, allowing + * reference to an external location as if it were within the phar archive. This + * is useful for writable temp files like databases + */ +PHP_METHOD(Phar, mount) +{ + char *fname, *arch, *entry, *path, *actual; + int fname_len, arch_len, entry_len, path_len, actual_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &path, &path_len, &actual, &actual_len) == FAILURE) { + return; + } + + fname = zend_get_executed_filename(TSRMLS_C); + fname_len = strlen(fname); + + if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len TSRMLS_CC)) { + phar_archive_data **pphar; + if (SUCCESS != zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **)&pphar)) { + /* TODO: throw exception */ + return; + } + if (SUCCESS != phar_mount_entry(*pphar, actual, actual_len, path, path_len TSRMLS_CC)) { + /* TODO: throw exception */ + return; + } + } +} +/* }}} */ + /* {{{ proto void Phar::webPhar([string alias, [string index, [string f404, [array mimetypes, [callback rewrites]]]]]) * mapPhar for web-based phars. Reads the currently executed file (a phar) * and registers its manifest. When executed in the CLI or CGI command-line sapi, @@ -3423,6 +3455,12 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_copy, 0, 0, 2) ZEND_ARG_INFO(0, oldfile) ZEND_END_ARG_INFO(); +static +ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_mount, 0, 0, 2) + ZEND_ARG_INFO(0, inphar) + ZEND_ARG_INFO(0, externalfile) +ZEND_END_ARG_INFO(); + static ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_conv, 0, 0, 0) ZEND_ARG_INFO(0, compression) @@ -3480,6 +3518,7 @@ zend_function_entry php_archive_methods[] = { PHP_ME(Phar, loadPhar, arginfo_phar_loadPhar, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL) PHP_ME(Phar, mapPhar, arginfo_phar_mapPhar, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL) PHP_ME(Phar, webPhar, arginfo_phar_webPhar, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL) + PHP_ME(Phar, mount, arginfo_phar_mount, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL) PHP_ME(Phar, mungServer, arginfo_phar_mungServer, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL) PHP_ME(Phar, interceptFileFuncs, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL) PHP_ME(Phar, getExtractList, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL) diff --git a/ext/phar/util.c b/ext/phar/util.c index 809835832e..f537601025 100644 --- a/ext/phar/util.c +++ b/ext/phar/util.c @@ -75,10 +75,16 @@ int phar_seek_efp(phar_entry_info *entry, off_t offset, int whence, off_t positi } /* mount an absolute path or uri to a path internal to the phar archive */ -int phar_mount_entry(phar_archive_data *phar, char *filename, int filename_len, char *path, int path_len, int is_dir TSRMLS_DC) +int phar_mount_entry(phar_archive_data *phar, char *filename, int filename_len, char *path, int path_len TSRMLS_DC) { phar_entry_info entry = {0}; php_stream_statbuf ssb; + const char *err; + int is_dir; + + if (phar_path_check(&path, &path_len, &err) > pcr_is_ok) { + return FAILURE; + } #if PHP_MAJOR_VERSION < 6 if (PG(safe_mode) && (!php_checkuid(filename, NULL, CHECKUID_ALLOW_ONLY_FILE))) { @@ -98,13 +104,13 @@ int phar_mount_entry(phar_archive_data *phar, char *filename, int filename_len, entry.is_mounted = 1; entry.is_crc_checked = 1; entry.fp_type = PHAR_TMP; - entry.is_dir = is_dir; if (SUCCESS != php_stream_stat_path(entry.link, &ssb)) { efree(entry.link); efree(entry.filename); return FAILURE; } + entry.is_dir = ssb.sb.st_mode & S_IFDIR ? 1 : 0; entry.uncompressed_filesize = entry.compressed_filesize = ssb.sb.st_size; entry.flags = ssb.sb.st_mode; if (SUCCESS == zend_hash_add(&phar->manifest, path, path_len, (void*)&entry, sizeof(phar_entry_info), NULL)) {