]> granicus.if.org Git - php/commitdiff
Initial support for PharData object.
authorSteph Fox <sfox@php.net>
Wed, 27 Feb 2008 21:34:26 +0000 (21:34 +0000)
committerSteph Fox <sfox@php.net>
Wed, 27 Feb 2008 21:34:26 +0000 (21:34 +0000)
Note: two tests currently fail. IMHO we should be throwing E_ERROR on encountering a corrupted archive, not trying to throw a trail of exceptions...
New tests still to be written, not all functionality is in place yet.

ext/phar/phar.c
ext/phar/phar_internal.h
ext/phar/phar_object.c
ext/phar/stream.c
ext/phar/tar.c
ext/phar/util.c
ext/phar/zip.c

index 14c28208cecce1edd5605a25da352fa3beb10a6d..2228530724bbf6acee8443c4e9f6c940cb11153e 100644 (file)
@@ -388,7 +388,7 @@ void phar_entry_remove(phar_entry_data *idata, char **error TSRMLS_DC) /* {{{ */
 /**
  * Open an already loaded phar
  */
-int phar_open_loaded(char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC) /* {{{ */
+int phar_open_loaded(char *fname, int fname_len, char *alias, int alias_len, int is_data, int options, phar_archive_data** pphar, char **error TSRMLS_DC) /* {{{ */
 {
        phar_archive_data *phar;
 #ifdef PHP_WIN32
@@ -420,6 +420,7 @@ int phar_open_loaded(char *fname, int fname_len, char *alias, int alias_len, int
                if (pphar) {
                        *pphar = phar;
                }
+               phar->is_data = is_data;
                return SUCCESS;
        } else {
 #ifdef PHP_WIN32
@@ -963,33 +964,63 @@ int phar_open_file(php_stream *fp, char *fname, int fname_len, char *alias, int
 /**
  * Create or open a phar for writing
  */
-int phar_open_or_create_filename(char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC) /* {{{ */
+int phar_open_or_create_filename(char *fname, int fname_len, char *alias, int alias_len, char *objname, int options, phar_archive_data** pphar, char **error TSRMLS_DC) /* {{{ */
 {
        char *ext_str;
-       int ext_len;
+       int ext_len, is_data = 0, zip = 0, tar = 0;
 
        if (error) {
                *error = NULL;
        }
 
-       if (phar_open_loaded(fname, fname_len, alias, alias_len, options, pphar, 0 TSRMLS_CC) == SUCCESS) {
-               if (pphar && !PHAR_G(readonly)) {
+       if (phar_detect_phar_fname_ext(fname, 1, &ext_str, &ext_len) == SUCCESS) {
+
+               if (ext_len >= sizeof(".zip")-1 && !memcmp((void *) ext_str, (void *) ".zip", sizeof(".zip")-1)) {
+                       zip = 1;
+               }
+                       
+               if (ext_len >= sizeof(".tar")-1 && !memcmp((void *) ext_str, (void *) ".tar", sizeof(".tar")-1)) {
+                       tar = 1;
+               }
+
+               if (tar || zip) {
+                       if (objname && strncmp(objname, "PharData", 8) != 0) {
+                               zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Cannot open '%s' as a Phar object. Use PharData::__construct() for a standard zip or tar archive", fname);
+                               return FAILURE;
+                       }
+                       is_data = 1;
+               } else {
+                       if (objname && strncmp(objname, "PharData", 8) == 0) {
+                               zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Cannot open '%s' as a PharData object. Use Phar::__construct() for archives other than .zip and .tar", fname);
+                               return FAILURE;
+                       }
+               }
+
+       } else {
+
+               zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Cannot open '%s' as a %s object, file extension (or combination) not recognised", fname, objname);
+               return FAILURE;
+       }
+
+       if (phar_open_loaded(fname, fname_len, alias, alias_len, is_data, options, pphar, 0 TSRMLS_CC) == SUCCESS) {
+               if (pphar && (!PHAR_G(readonly) || is_data)) {
                        (*pphar)->is_writeable = 1;
                }
                return SUCCESS;
        }
 
-       if (phar_detect_phar_fname_ext(fname, 1, &ext_str, &ext_len) == SUCCESS) {
-               if (ext_len >= sizeof(".phar.zip")-1 && !memcmp((void *) ext_str, (void *) ".phar.zip", sizeof(".phar.zip")-1)) {
-                       /* assume zip-based phar */
-                       return phar_open_or_create_zip(fname, fname_len, alias, alias_len, options, pphar, error TSRMLS_CC);
-               }
-               if (ext_len >= sizeof(".phar.tar")-1 && !memcmp((void *) ext_str, (void *) ".phar.tar", sizeof(".phar.tar")-1)) {
-                       /* assume tar-based phar */
-                       return phar_open_or_create_tar(fname, fname_len, alias, alias_len, options, pphar, error TSRMLS_CC);
-               }
+       if ((ext_len >= sizeof(".phar.zip")-1 && !memcmp((void *) ext_str, (void *) ".phar.zip", sizeof(".phar.zip")-1)) || zip) {
+               // assume zip-based phar
+               return phar_open_or_create_zip(fname, fname_len, alias, alias_len, is_data, options, pphar, error TSRMLS_CC);
        }
+
+       if ((ext_len >= sizeof(".phar.tar")-1 && !memcmp((void *) ext_str, (void *) ".phar.tar", sizeof(".phar.tar")-1)) || tar) {
+               // assume tar-based phar
+               return phar_open_or_create_tar(fname, fname_len, alias, alias_len, is_data, options, pphar, error TSRMLS_CC);
+       }
+
        return phar_create_or_parse_filename(fname, fname_len, alias, alias_len, options, pphar, error TSRMLS_CC);
+
 }
 
 int phar_create_or_parse_filename(char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC) /* {{{ */
@@ -1109,7 +1140,7 @@ int phar_open_filename(char *fname, int fname_len, char *alias, int alias_len, i
                *error = NULL;
        }
        
-       if (phar_open_loaded(fname, fname_len, alias, alias_len, options, pphar, error TSRMLS_CC) == SUCCESS) {
+       if (phar_open_loaded(fname, fname_len, alias, alias_len, 0, options, pphar, error TSRMLS_CC) == SUCCESS) {
                return SUCCESS;
        } else if (error && *error) {
                return FAILURE;
@@ -1303,43 +1334,64 @@ static int phar_open_fp(php_stream* fp, char *fname, int fname_len, char *alias,
 int phar_detect_phar_fname_ext(const char *filename, int check_length, char **ext_str, int *ext_len) /* {{{ */
 {
        char end;
-       char *pos_p = strstr(filename, ".phar.php");
-       char *pos_zi = strstr(filename, ".phar.zip");
-       char *pos_zi2 = strstr(filename, ".phar.zip.php");
-       char *pos_t = strstr(filename, ".phar.tar");
-       char *pos_t2 = strstr(filename, ".phar.tar.php");
-       char *pos_z = strstr(filename, ".phar.gz");
-       char *pos_b = strstr(filename, ".phar.bz2");
-
-       if (pos_p) {
-               if (pos_z) {
-                       return FAILURE;
-               }
-               *ext_str = pos_p;
+       char *pos_t = strstr(filename, ".tar");
+       char *pos_z = strstr(filename, ".zip");
+       char *pos_tg = strstr(filename, ".tar.gz");
+       char *pos_tb = strstr(filename, ".tar.bz2");
+       char *pos_pg = strstr(filename, ".phar.gz");
+       char *pos_pb = strstr(filename, ".phar.bz2");
+       char *pos_pp = strstr(filename, ".phar.php");
+       char *pos_pt = strstr(filename, ".phar.tar");
+       char *pos_pz = strstr(filename, ".phar.zip");
+       char *pos_ptg = strstr(filename, ".phar.tar.gz");
+       char *pos_ptb = strstr(filename, ".phar.tar.bz2");
+       char *pos_ptp = strstr(filename, ".phar.tar.php");
+       char *pos_pzp = strstr(filename, ".phar.zip.php");
+
+       if (pos_pzp) {
+               *ext_str = pos_pzp;
+               *ext_len = 13;
+       } else if (pos_ptp) {
+               *ext_str = pos_ptp;
+               *ext_len = 13;
+       } else if (pos_ptb) {
+               *ext_str = pos_ptb;
+               *ext_len = 13;
+       } else if (pos_ptg) {
+               *ext_str = pos_ptg;
+               *ext_len = 12;
+       } else if (pos_pz) {
+               *ext_str = pos_pz;
                *ext_len = 9;
-       } else if (pos_z) {
-               *ext_str = pos_z;
-               *ext_len = 8;
-       } else if (pos_b) {
-               *ext_str = pos_b;
+       } else if (pos_pt) {
+               *ext_str = pos_pt;
                *ext_len = 9;
-       } else if (pos_zi2) {
-               *ext_str = pos_zi2;
-               *ext_len = 13;
-       } else if (pos_zi) {
-               *ext_str = pos_zi;
+       } else if (pos_pp) {
+               *ext_str = pos_pp;
                *ext_len = 9;
-       } else if (pos_t2) {
-               *ext_str = pos_t2;
-               *ext_len = 13;
+       } else if (pos_pb) {
+               *ext_str = pos_pb;
+               *ext_len = 9;
+       } else if (pos_pg) {
+               *ext_str = pos_pg;
+               *ext_len = 8;
+       } else if (pos_tb) {
+               *ext_str = pos_tb;
+               *ext_len = 8;
+       } else if (pos_tg) {
+               *ext_str = pos_tg;
+               *ext_len = 7;
+       } else if (pos_z) {
+               *ext_str = pos_z;
+               *ext_len = 4;
        } else if (pos_t) {
                *ext_str = pos_t;
-               *ext_len = 9;
-       } else if ((pos_p = strstr(filename, ".phar")) != NULL && pos_p[4] != '\0') {
-               *ext_str = pos_p;
+               *ext_len = 4;
+       } else if ((pos_pp = strstr(filename, ".phar")) != NULL && pos_pp[4] != '\0') {
+               *ext_str = pos_pp;
                *ext_len = 5;
-       } else if ((pos_p = strstr(filename, ".php")) != NULL && pos_p[4] != '\0') {
-               *ext_str = pos_p;
+       } else if ((pos_pp = strstr(filename, ".php")) != NULL && pos_pp[4] != '\0') {
+               *ext_str = pos_pp;
                *ext_len = 4;
        } else {
                /* We have an alias with no extension, so locate the first / and fail */
@@ -1571,7 +1623,7 @@ int phar_open_compiled_file(char *alias, int alias_len, char **error TSRMLS_DC)
        fname = zend_get_executed_filename(TSRMLS_C);
        fname_len = strlen(fname);
 
-       if (phar_open_loaded(fname, fname_len, alias, alias_len, REPORT_ERRORS, NULL, 0 TSRMLS_CC) == SUCCESS) {
+       if (phar_open_loaded(fname, fname_len, alias, alias_len, 0, REPORT_ERRORS, NULL, 0 TSRMLS_CC) == SUCCESS) {
                return SUCCESS;
        }
 
index 2f3e2762df31b5af0b6d5479fa20eceb80a2752c..7cc44b4fc88ca0fdd5d1928b838979188298769b 100755 (executable)
@@ -285,6 +285,8 @@ struct _phar_archive_data {
        int                      is_zip:1;
        /* tar-based phar variables */
        int                      is_tar:1;
+       /* PharData variables       */
+       int                      is_data:1;
 };
 
 #define PHAR_MIME_PHP '\0'
@@ -363,11 +365,11 @@ void phar_object_init(TSRMLS_D);
 
 int phar_open_entry_file(phar_archive_data *phar, phar_entry_info *entry, char **error TSRMLS_DC);
 int phar_open_filename(char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC);
-int phar_open_or_create_filename(char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC);
+int phar_open_or_create_filename(char *fname, int fname_len, char *alias, int alias_len, char *objname, int options, phar_archive_data** pphar, char **error TSRMLS_DC);
 int phar_create_or_parse_filename(char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC);
 int phar_open_compiled_file(char *alias, int alias_len, char **error TSRMLS_DC);
 int phar_get_archive(phar_archive_data **archive, char *fname, int fname_len, char *alias, int alias_len, char **error TSRMLS_DC);
-int phar_open_loaded(char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC);
+int phar_open_loaded(char *fname, int fname_len, char *alias, int alias_len, int is_data, int options, phar_archive_data** pphar, char **error TSRMLS_DC);
 
 /* utility functions */
 char *phar_create_default_stub(const char *index_php, const char *web_index, size_t *len, char **error TSRMLS_DC);
@@ -393,12 +395,12 @@ int phar_open_archive_fp(phar_archive_data *phar TSRMLS_DC);
 /* tar functions in tar.c */
 int phar_is_tar(char *buf);
 int phar_open_tarfile(php_stream* fp, char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, php_uint32 compression, char **error TSRMLS_DC);
-int phar_open_or_create_tar(char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC);
+int phar_open_or_create_tar(char *fname, int fname_len, char *alias, int alias_len, int is_data, int options, phar_archive_data** pphar, char **error TSRMLS_DC);
 int phar_tar_flush(phar_archive_data *phar, char *user_stub, long len, int defaultstub, char **error TSRMLS_DC);
 
 /* zip functions in zip.c */
 int phar_open_zipfile(php_stream *fp, char *fname, int fname_len, char *alias, int alias_len, phar_archive_data** pphar, char **error TSRMLS_DC);
-int phar_open_or_create_zip(char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC);
+int phar_open_or_create_zip(char *fname, int fname_len, char *alias, int alias_len, int is_data, int options, phar_archive_data** pphar, char **error TSRMLS_DC);
 int phar_zip_flush(phar_archive_data *archive, char *user_stub, long len, int defaultstub, char **error TSRMLS_DC);
 
 #ifdef PHAR_MAIN
index 1fb3f2f34724e45b7f9314280d10043ae11a5687..4bbac352aa2c76a32b40559b46b57ff04cd6c513 100755 (executable)
@@ -23,6 +23,7 @@
 #include "func_interceptors.h"
 
 static zend_class_entry *phar_ce_archive;
+static zend_class_entry *phar_ce_data;
 static zend_class_entry *phar_ce_PharException;
 
 #if HAVE_SPL
@@ -1099,6 +1100,8 @@ static spl_other_handler phar_spl_foreign_handler = {
 
 /* {{{ proto void Phar::__construct(string fname [, int flags [, string alias]])
  * Construct a Phar archive object
+ * {{{ proto void PharData::__construct(string fname [, int flags [, string alias]])
+ * Construct a PharData archive object
  */
 PHP_METHOD(Phar, __construct)
 {
@@ -1106,7 +1109,7 @@ PHP_METHOD(Phar, __construct)
        zend_throw_exception_ex(zend_exception_get_default(TSRMLS_C), 0 TSRMLS_CC, "Cannot instantiate Phar object without SPL extension");
 #else
        char *fname, *alias = NULL, *error, *arch, *entry = NULL, *save_fname;
-       int fname_len, alias_len = 0, arch_len, entry_len;
+       int fname_len, alias_len = 0, arch_len, entry_len, is_data;
        long flags = 0;
        phar_archive_object *phar_obj;
        phar_archive_data   *phar_data;
@@ -1124,7 +1127,7 @@ PHP_METHOD(Phar, __construct)
        }
 
        if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len TSRMLS_CC)) {
-               /* use arch for fname instead of fname */
+               /* use arch (the basename for the archive) for fname instead of fname */
                /* this allows support for RecursiveDirectoryIterator of subdirectories */
                save_fname = fname;
 #ifdef PHP_WIN32
@@ -1140,7 +1143,9 @@ PHP_METHOD(Phar, __construct)
                phar_unixify_path_separators(arch, arch_len);
 #endif
        }
-       if (phar_open_or_create_filename(fname, fname_len, alias, alias_len, REPORT_ERRORS, &phar_data, &error TSRMLS_CC) == FAILURE) {
+
+       if (phar_open_or_create_filename(fname, fname_len, alias, alias_len, phar_obj->std.ce->name, REPORT_ERRORS, &phar_data, &error TSRMLS_CC) == FAILURE) {
+
                if (fname == arch) {
                        efree(arch);
                        fname = save_fname;
@@ -1162,6 +1167,8 @@ PHP_METHOD(Phar, __construct)
                efree(arch);
                fname = save_fname;
        }
+
+       is_data = phar_data->is_data;
        phar_data->refcount++;
        phar_obj->arc.archive = phar_data;
        phar_obj->spl.oth_handler = &phar_spl_foreign_handler;
@@ -1172,6 +1179,7 @@ PHP_METHOD(Phar, __construct)
        } else {
                fname_len = spprintf(&fname, 0, "phar://%s", phar_data->fname);
        }
+
        INIT_PZVAL(&arg1);
        ZVAL_STRINGL(&arg1, fname, fname_len, 0);
 
@@ -1185,6 +1193,7 @@ PHP_METHOD(Phar, __construct)
                        &spl_ce_RecursiveDirectoryIterator->constructor, "__construct", NULL, &arg1);
        }
 
+       phar_obj->arc.archive->is_data = is_data;
        phar_obj->spl.info_class = phar_ce_entry;
 
        efree(fname);
@@ -1592,10 +1601,12 @@ static void phar_convert_to_other(phar_archive_data *source, int convert, char *
 {
        phar_archive_data phar = {0};
        char *error;
+       int is_data;
        phar_entry_info *entry, newentry;
 
-       /* set whole-archive compression from parameter */
+       /* set whole-archive compression and type from parameter */
        phar.flags = flags;
+
        switch (convert) {
                case 1 :
                        phar.is_tar = 1;
@@ -1697,12 +1708,14 @@ static void phar_convert_to_other(phar_archive_data *source, int convert, char *
        if (source->fp && source->refcount == 1) {
                php_stream_close(source->fp);
        }
+
        source->fp = phar.fp;
        /* don't free stuff */
        phar.manifest.pDestructor = NULL;
        zend_hash_destroy(&(phar.manifest));
        source->is_zip = phar.is_zip;
        source->is_tar = phar.is_tar;
+
        if (phar.is_zip || phar.is_tar) {
                source->internal_file_start = source->halt_offset = 0;
        }
@@ -1843,6 +1856,12 @@ PHP_METHOD(Phar, convertToPhar)
        int ext_len = 0;
        PHAR_ARCHIVE_OBJECT();
 
+       if (phar_obj->arc.archive->is_data) {
+               zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
+                       "A plain %s archive cannot be converted to a Phar archive", phar_obj->arc.archive->is_tar ? "tar" : "zip");
+               return;
+       }
+
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ls", &method, &ext, &ext_len) == FAILURE) {
                return;
        }
@@ -1989,6 +2008,12 @@ PHP_METHOD(Phar, setAlias)
                return;
        }
 
+       if (phar_obj->arc.archive->is_data) {
+               zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
+                       "A Phar alias cannot be set in a plain %s archive", phar_obj->arc.archive->is_tar ? "tar" : "zip");
+               return;
+       }
+
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &alias, &alias_len) == SUCCESS) {
                if (alias_len == phar_obj->arc.archive->alias_len && memcmp(phar_obj->arc.archive->alias, alias, alias_len) == 0) {
                        RETURN_TRUE;
@@ -2114,6 +2139,12 @@ PHP_METHOD(Phar, setStub)
                return;
        }
 
+       if (phar_obj->arc.archive->is_data) {
+               zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
+                       "A Phar stub cannot be set in a plain %s archive", phar_obj->arc.archive->is_tar ? "tar" : "zip");
+               return;
+       }
+
        if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &zstub, &len) == SUCCESS) {
                if ((php_stream_from_zval_no_verify(stream, &zstub)) != NULL) {
                        if (len > 0) {
@@ -2164,6 +2195,12 @@ PHP_METHOD(Phar, setStub)
        size_t stub_len = 0;
        PHAR_ARCHIVE_OBJECT();
 
+       if (phar_obj->arc.archive->is_data) {
+               zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
+                       "A Phar stub cannot be set in a plain %s archive", phar_obj->arc.archive->is_tar ? "tar" : "zip");
+               return;
+       }
+
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!s", &index, &index_len, &webindex, &webindex_len) == FAILURE) {
                RETURN_FALSE;
        }
@@ -3624,12 +3661,21 @@ void phar_object_init(TSRMLS_D) /* {{{ */
 
        zend_class_implements(phar_ce_archive TSRMLS_CC, 2, spl_ce_Countable, zend_ce_arrayaccess);
 
+       INIT_CLASS_ENTRY(ce, "PharData", php_archive_methods);
+       phar_ce_data = zend_register_internal_class_ex(&ce, spl_ce_RecursiveDirectoryIterator, NULL  TSRMLS_CC);
+
+       zend_class_implements(phar_ce_data TSRMLS_CC, 2, spl_ce_Countable, zend_ce_arrayaccess);
+
        INIT_CLASS_ENTRY(ce, "PharFileInfo", php_entry_methods);
        phar_ce_entry = zend_register_internal_class_ex(&ce, spl_ce_SplFileInfo, NULL  TSRMLS_CC);
 #else
        INIT_CLASS_ENTRY(ce, "Phar", php_archive_methods);
        phar_ce_archive = zend_register_internal_class(&ce TSRMLS_CC);
        phar_ce_archive->ce_flags |= ZEND_ACC_FINAL_CLASS;
+
+       INIT_CLASS_ENTRY(ce, "PharData", php_archive_methods);
+       phar_ce_data = zend_register_internal_class(&ce TSRMLS_CC);
+       phar_ce_data->ce_flags |= ZEND_ACC_FINAL_CLASS;
 #endif
 
        REGISTER_PHAR_CLASS_CONST_LONG(phar_ce_archive, "BZ2", PHAR_ENT_COMPRESSED_BZ2)
index deeb968e6e73d6e8ce811ce02e4e4d1b7fdbf179..210dc656fcaaa2819fc387df62c9a0dc3c99aea5 100644 (file)
@@ -116,7 +116,7 @@ php_url* phar_open_url(php_stream_wrapper *wrapper, char *filename, char *mode,
                                php_url_free(resource);
                                return NULL;
                        }
-                       if (phar_open_or_create_filename(resource->host, arch_len, NULL, 0, options, NULL, &error TSRMLS_CC) == FAILURE)
+                       if (phar_open_or_create_filename(resource->host, arch_len, NULL, 0, NULL, options, NULL, &error TSRMLS_CC) == FAILURE)
                        {
                                if (error) {
                                        if (!(options & PHP_STREAM_URL_STAT_QUIET)) {
index 52ab15cc3e04dda82b0535daad7a5495dd80d12b..5c1d19c3567041b8f1f2e9a901f4ebc06450e612 100644 (file)
@@ -116,7 +116,7 @@ int phar_is_tar(char *buf)
        return ret;
 }
 
-int phar_open_or_create_tar(char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC) /* {{{ */
+int phar_open_or_create_tar(char *fname, int fname_len, char *alias, int alias_len, int is_data, int options, phar_archive_data** pphar, char **error TSRMLS_DC) /* {{{ */
 {
        phar_archive_data *phar;
        int ret = phar_create_or_parse_filename(fname, fname_len, alias, alias_len, options, &phar, error TSRMLS_CC);
@@ -124,12 +124,23 @@ int phar_open_or_create_tar(char *fname, int fname_len, char *alias, int alias_l
        if (pphar) {
                *pphar = phar;
        }
+
+       phar->is_data = is_data;
+
+       if (is_data) {
+               phar->is_writeable;
+               phar->alias = NULL;
+               phar->alias_len = 0;
+       }
+
        if (FAILURE == ret) {
                return FAILURE;
        }
+
        if (phar->is_tar) {
                return ret;
        }
+
        if (phar->is_brandnew) {
                phar->is_tar = 1;
                phar->internal_file_start = 0;
@@ -460,6 +471,10 @@ int phar_tar_flush(phar_archive_data *phar, char *user_stub, long len, int defau
        entry.phar = phar;
        entry.fp_type = PHAR_MOD;
 
+       if (phar->is_data) {
+               goto nostub;
+       }
+
        /* set alias */
        if (!phar->is_temporary_alias && phar->alias_len) {
                entry.filename = estrndup(".phar/alias.txt", sizeof(".phar/alias.txt")-1);
@@ -583,6 +598,8 @@ int phar_tar_flush(phar_archive_data *phar, char *user_stub, long len, int defau
                }
        }
 
+nostub:
+
        if (phar->fp && !phar->is_brandnew) {
                oldfile = phar->fp;
                closeoldfile = 0;
index 09d7b11a612dd9a42b1d22bb6986419799ae38ae..b078c08c90f89694e19d4cde3b9f8a4b360be12a 100644 (file)
@@ -80,17 +80,33 @@ void phar_rename_archive(phar_archive_data *phar, char *ext TSRMLS_DC)
 
        if (!ext) {
                if (phar->is_zip) {
-                       ext = "phar.zip";
+                       if (phar->is_data) {
+                               ext = "zip";
+                       } else {
+                               ext = "phar.zip";
+                       }
                } else if (phar->is_tar) {
                        switch (phar->flags) {
                                case PHAR_FILE_COMPRESSED_GZ:
-                                       ext = "phar.tar.gz";
+                                       if (phar->is_data) {
+                                               ext = "tar.gz";
+                                       } else {
+                                               ext = "phar.tar.gz";
+                                       }
                                        break;
                                case PHAR_FILE_COMPRESSED_BZ2:
-                                       ext = "phar.tar.bz2";
+                                       if (phar->is_data) {
+                                               ext = "tar.bz2";
+                                       } else {
+                                               ext = "phar.tar.bz2";
+                                       }
                                        break;
                                default:
-                                       ext = "phar.tar";
+                                       if (phar->is_data) {
+                                               ext = "tar";
+                                       } else {
+                                               ext = "phar.tar";
+                                       }
                        }
                } else {
                        switch (phar->flags) {
@@ -123,7 +139,7 @@ void phar_rename_archive(phar_archive_data *phar, char *ext TSRMLS_DC)
        efree(basepath);
        efree(newname);
 
-       if (!phar->is_zip && !phar->is_tar) {
+       if (!strncmp(ext, "zip", 3) && !strncmp(ext, "tar", 3)) {
                phar->alias = estrndup(newpath, strlen(newpath));
                phar->alias_len = strlen(newpath);
                zend_hash_update(&(PHAR_GLOBALS->phar_alias_map), newpath, strlen(newpath), (void*)&phar, sizeof(phar_archive_data*), NULL);
index 166fd2ae7c6307c060beb93d58329a30bb9553b2..f76b7b0b83fd1f26ba301336919b0ffe5dbfcf7b 100644 (file)
@@ -374,7 +374,7 @@ foundit:
 /**
  * Create or open a zip-based phar for writing
  */
-int phar_open_or_create_zip(char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC) /* {{{ */
+int phar_open_or_create_zip(char *fname, int fname_len, char *alias, int alias_len, int is_data, int options, phar_archive_data** pphar, char **error TSRMLS_DC) /* {{{ */
 {
        phar_archive_data *phar;
        int ret = phar_create_or_parse_filename(fname, fname_len, alias, alias_len, options, &phar, error TSRMLS_CC);
@@ -382,9 +382,19 @@ int phar_open_or_create_zip(char *fname, int fname_len, char *alias, int alias_l
        if (pphar) {
                *pphar = phar;
        }
+
+       phar->is_data = is_data;
+
+       if (is_data) {
+               phar->is_writeable;
+               phar->alias = NULL;
+               phar->alias_len = 0;
+       }
+
        if (FAILURE == ret) {
                return FAILURE;
        }
+
        if (phar->is_zip) {
                return ret;
        }
@@ -662,6 +672,10 @@ int phar_zip_flush(phar_archive_data *phar, char *user_stub, long len, int defau
        entry.phar = phar;
        entry.fp_type = PHAR_MOD;
 
+       if (phar->is_data) {
+               goto nostub;
+       }
+
        /* set alias */
        if (!phar->is_temporary_alias && phar->alias_len) {
                entry.fp = php_stream_fopen_tmpfile();
@@ -797,6 +811,8 @@ int phar_zip_flush(phar_archive_data *phar, char *user_stub, long len, int defau
                }
        }
 
+nostub:
+
        if (phar->fp && !phar->is_brandnew) {
                oldfile = phar->fp;
                closeoldfile = 0;