From: Steph Fox Date: Wed, 27 Feb 2008 21:34:26 +0000 (+0000) Subject: Initial support for PharData object. X-Git-Tag: RELEASE_2_0_0a1~307 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=001ffec19f101fbab24046da16504c5f536c9f38;p=php Initial support for PharData object. 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. --- diff --git a/ext/phar/phar.c b/ext/phar/phar.c index 14c28208ce..2228530724 100644 --- a/ext/phar/phar.c +++ b/ext/phar/phar.c @@ -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; } diff --git a/ext/phar/phar_internal.h b/ext/phar/phar_internal.h index 2f3e2762df..7cc44b4fc8 100755 --- a/ext/phar/phar_internal.h +++ b/ext/phar/phar_internal.h @@ -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 diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index 1fb3f2f347..4bbac352aa 100755 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -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) diff --git a/ext/phar/stream.c b/ext/phar/stream.c index deeb968e6e..210dc656fc 100644 --- a/ext/phar/stream.c +++ b/ext/phar/stream.c @@ -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)) { diff --git a/ext/phar/tar.c b/ext/phar/tar.c index 52ab15cc3e..5c1d19c356 100644 --- a/ext/phar/tar.c +++ b/ext/phar/tar.c @@ -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; diff --git a/ext/phar/util.c b/ext/phar/util.c index 09d7b11a61..b078c08c90 100644 --- a/ext/phar/util.c +++ b/ext/phar/util.c @@ -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); diff --git a/ext/phar/zip.c b/ext/phar/zip.c index 166fd2ae7c..f76b7b0b83 100644 --- a/ext/phar/zip.c +++ b/ext/phar/zip.c @@ -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;