]> granicus.if.org Git - php/commitdiff
begin work on ability to mount files from external locations as if they were inside...
authorGreg Beaver <cellog@php.net>
Fri, 15 Feb 2008 05:01:40 +0000 (05:01 +0000)
committerGreg Beaver <cellog@php.net>
Fri, 15 Feb 2008 05:01:40 +0000 (05:01 +0000)
ext/phar/dirstream.c
ext/phar/phar_internal.h
ext/phar/util.c

index 81a7945526ac5b202e0d8770aec302f3425d0283..22b68906d81bbf33ee1cb4cf9556f56eca53d31f 100644 (file)
@@ -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);
index 3834b60995659ec21d6e63666f3ff3bc6b576f85..e25640204904a205c5757f75117d5ebcf8ac29cc 100755 (executable)
@@ -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;
index 47aed823fca1c613c0b6bf40b283a4a15ed095b5..bdb0584d1dee80b350472581b3955495a0b64c5c 100644 (file)
@@ -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;