From: Greg Beaver Date: Fri, 15 Feb 2008 05:01:40 +0000 (+0000) Subject: begin work on ability to mount files from external locations as if they were inside... X-Git-Tag: RELEASE_2_0_0a1~469 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=54ff8c3a8f91605b39afc69ddef3428c9f61a992;p=php begin work on ability to mount files from external locations as if they were inside of a phar archive --- diff --git a/ext/phar/dirstream.c b/ext/phar/dirstream.c index 81a7945526..22b68906d8 100644 --- a/ext/phar/dirstream.c +++ b/ext/phar/dirstream.c @@ -376,6 +376,11 @@ php_stream *phar_wrapper_open_dir(php_stream_wrapper *wrapper, char *path, char php_url_free(resource); return NULL; } else if (entry && entry->is_dir) { + /*if (entry->is_mounted) { + external directory, TODO: construct an internal dirstream based on this actual dir's dirstream + php_url_free(resource); + return php_stream_opendir(entry->link, options, context); + }*/ internal_file = estrdup(internal_file); php_url_free(resource); return phar_make_dirstream(internal_file, &phar->manifest TSRMLS_CC); diff --git a/ext/phar/phar_internal.h b/ext/phar/phar_internal.h index 3834b60995..e256402049 100755 --- a/ext/phar/phar_internal.h +++ b/ext/phar/phar_internal.h @@ -201,7 +201,10 @@ enum phar_fp_type { /* uncompressed file pointer phar_archive_data->uncompressed_fp */ PHAR_UFP, /* modified file pointer phar_entry_info->fp */ - PHAR_MOD + PHAR_MOD, + /* temporary manifest entry (file outside of the phar mapped to a location inside the phar) + this entry stores the stream to open in link (normally used for tars, but we steal it here) */ + PHAR_TMP }; typedef struct _phar_archive_data phar_archive_data; @@ -233,6 +236,9 @@ typedef struct _phar_entry_info { int is_modified:1; int is_deleted:1; int is_dir:1; + /* this flag is used for mounted entries (external files mapped to location + inside a phar */ + int is_mounted:1; /* used when iterating */ int is_temp_dir:1; phar_archive_data *phar; diff --git a/ext/phar/util.c b/ext/phar/util.c index 47aed823fc..bdb0584d1d 100644 --- a/ext/phar/util.c +++ b/ext/phar/util.c @@ -34,7 +34,13 @@ php_stream *phar_get_efp(phar_entry_info *entry) return entry->phar->fp; } else if (entry->fp_type == PHAR_UFP) { return entry->phar->ufp; + } else if (entry->fp_type == PHAR_MOD) { + return entry->fp; } else { + /* temporary manifest entry */ + if (!entry->fp) { + entry->fp = php_stream_open_wrapper(entry->link, "rb", STREAM_MUST_SEEK|0, NULL); + } return entry->fp; } } @@ -67,6 +73,33 @@ int phar_seek_efp(phar_entry_info *entry, off_t offset, int whence, off_t positi return php_stream_seek(fp, temp, SEEK_SET); } +/* 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) +{ + phar_entry_info entry = {0}; + +#if PHP_MAJOR_VERSION < 6 + if (PG(safe_mode) && (!php_checkuid(filename, NULL, CHECKUID_ALLOW_ONLY_FILE))) { + return FAILURE; + } +#endif + + /* only check openbasedir for files, not for phar streams */ + if (!strstr(filename, "phar://") && php_check_open_basedir(filename TSRMLS_CC)) { + return FAILURE; + } + + entry.phar = phar; + entry.filename = estrndup(path, path_len); + entry.filename_len = path_len; + entry.link = estrndup(filename, filename_len); + entry.is_mounted = 1; + entry.is_crc_checked = 1; + entry.fp_type = PHAR_TMP; + entry.is_dir = is_dir; + return zend_hash_add(&phar->manifest, path, path_len, (void*)&entry, sizeof(phar_entry_info), NULL); +} + char *phar_find_in_include_path(char *file, char *entry, phar_archive_data *phar TSRMLS_DC) /* {{{ */ { char *path = PG(include_path), *pathbuf, *ptr, *end;