]> granicus.if.org Git - php/commitdiff
- MFB major fixes
authorSteph Fox <sfox@php.net>
Sat, 24 May 2008 14:18:31 +0000 (14:18 +0000)
committerSteph Fox <sfox@php.net>
Sat, 24 May 2008 14:18:31 +0000 (14:18 +0000)
   * found felipe's segfault in util.c and fixed the segfault (3 tests fail due to odd behavior of . and .. on this machine)
   * fixed serious flaws in the setting/resetting of is_data - now it works properly.  Assume
     all new PharData are tar-based, and allow passing Phar::ZIP to PharData constructor to override this
   * fix broken earlier commit, introduced segfault that broke 20 tests here

ext/phar/phar.c
ext/phar/phar_object.c
ext/phar/tar.c
ext/phar/util.c
ext/phar/zip.c

index f432c0692604059d043146ad8a17a48384c4e354..0b595a9c8fba6d2178823684bd6cbf0ab7f4f92f 100644 (file)
@@ -406,7 +406,6 @@ int phar_open_loaded(char *fname, int fname_len, char *alias, int alias_len, int
                                }
                        }
                }
-               phar->is_data = is_data && (phar->is_tar || phar->is_zip);
                if (pphar) {
                        *pphar = phar;
                }
@@ -1033,12 +1032,12 @@ check_file:
        }
 
        if (ext_len > 3 && (z = memchr(ext_str, 'z', ext_len)) && ((ext_str + ext_len) - z >= 2) && !memcmp(z + 1, "ip", 2)) {
-               // assume zip-based phar
+               /* 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 > 3 && (z = memchr(ext_str, 't', ext_len)) && ((ext_str + ext_len) - z >= 2) && !memcmp(z + 1, "ar", 2)) {
-               // assume tar-based phar
+               /* assume tar-based phar */
                return phar_open_or_create_tar(fname, fname_len, alias, alias_len, is_data, options, pphar, error TSRMLS_CC);
        }
 
@@ -1140,6 +1139,9 @@ int phar_create_or_parse_filename(char *fname, int fname_len, char *alias, int a
        if (is_data) {
                alias = NULL;
                alias_len = 0;
+               mydata->is_data = 1;
+               /* assume tar format, PharData can specify other */
+               mydata->is_tar = 1;
        } else {
                phar_archive_data **fd_ptr;
 
index 728bfe2183fd1ca757d1bc3b4305d6460edc4e24..fd16d627bf5fe4d675c5782d1426dae94115766f 100755 (executable)
@@ -1120,7 +1120,7 @@ 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]])
+ * {{{ proto void PharData::__construct(string fname [[, int flags [, string alias]], int file format = Phar::TAR])
  * Construct a PharData archive object
  */
 PHP_METHOD(Phar, __construct)
@@ -1130,22 +1130,13 @@ PHP_METHOD(Phar, __construct)
 #else
        char *fname, *alias = NULL, *error, *arch = NULL, *entry = NULL, *save_fname, *objname;
        int fname_len, alias_len = 0, arch_len, entry_len, is_data;
-       long flags = 0;
+       long flags = 0, format = 0;
        phar_archive_object *phar_obj;
        phar_archive_data   *phar_data;
        zval *zobj = getThis(), arg1, arg2;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ls!", &fname, &fname_len, &flags, &alias, &alias_len) == FAILURE) {
-               return;
-       }
-
        phar_obj = (phar_archive_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
 
-       if (phar_obj->arc.archive) {
-               zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Cannot call constructor twice");
-               return;
-       }
-
        PHAR_STR(phar_obj->std.ce->name, objname);
 
        if (!strncmp(objname, "PharData", 8)) {
@@ -1154,6 +1145,21 @@ PHP_METHOD(Phar, __construct)
                is_data = 0;
        }
 
+       if (is_data) {
+               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ls!l", &fname, &fname_len, &flags, &alias, &alias_len, &format) == FAILURE) {
+                       return;
+               }
+       } else {
+               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ls!", &fname, &fname_len, &flags, &alias, &alias_len) == FAILURE) {
+                       return;
+               }
+       }
+
+       if (phar_obj->arc.archive) {
+               zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Cannot call constructor twice");
+               return;
+       }
+
        if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, !is_data, 2 TSRMLS_CC)) {
                /* use arch (the basename for the archive) for fname instead of fname */
                /* this allows support for RecursiveDirectoryIterator of subdirectories */
@@ -1193,11 +1199,28 @@ PHP_METHOD(Phar, __construct)
                return;
        }
 
+       if (is_data && phar_data->is_tar && phar_data->is_brandnew && format == PHAR_FORMAT_ZIP) {
+               phar_data->is_zip = 1;
+               phar_data->is_tar = 0;
+       }
+
        if (fname == arch) {
                efree(arch);
                fname = save_fname;
        }
 
+       if ((is_data && !phar_data->is_data) || (!is_data && phar_data->is_data)) {
+               if (is_data) {
+                       zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
+                               "PharData class can only be used for non-executable tar and zip archives");
+               } else {
+                       zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
+                               "Phar class can only be used for executable tar and zip archives");
+               }
+               efree(entry);
+               return;
+       }
+
        is_data = phar_data->is_data;
        ++(phar_data->refcount);
        phar_obj->arc.archive = phar_data;
@@ -1844,7 +1867,7 @@ static zval *phar_rename_archive(phar_archive_data *phar, char *ext, zend_bool c
        char *error;
        const char *pcr_error;
        int ext_len = ext ? strlen(ext) : 0;
-       phar_archive_data **pphar;
+       phar_archive_data **pphar = NULL;
 
        if (!ext) {
                if (phar->is_zip) {
@@ -1912,6 +1935,7 @@ static zval *phar_rename_archive(phar_archive_data *phar, char *ext, zend_bool c
        basepath = estrndup(oldpath, strlen(oldpath) - strlen(oldname));
        phar->fname_len = spprintf(&newpath, 0, "%s%s", basepath, newname);
        phar->fname = newpath;
+       phar->ext = newpath + phar->fname_len - strlen(ext) - 1;
        efree(basepath);
        efree(newname);
 
@@ -1926,6 +1950,7 @@ static zval *phar_rename_archive(phar_archive_data *phar, char *ext, zend_bool c
                                phar->fp = NULL;
                                phar_destroy_phar_data(phar TSRMLS_CC);
                                phar = *pphar;
+                               phar->refcount++;
                                newpath = oldpath;
                                goto its_ok;
                        }
@@ -1963,7 +1988,7 @@ its_ok:
                phar->alias_len = 0;
        }
 
-       if (SUCCESS != zend_hash_update(&(PHAR_GLOBALS->phar_fname_map), newpath, phar->fname_len, (void*)&phar, sizeof(phar_archive_data*), NULL)) {
+       if ((!pphar || phar == *pphar) && SUCCESS != zend_hash_update(&(PHAR_GLOBALS->phar_fname_map), newpath, phar->fname_len, (void*)&phar, sizeof(phar_archive_data*), NULL)) {
                efree(oldpath);
                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Unable to add newly converted phar \"%s\" to the list of phars", phar->fname);
                return NULL;
@@ -4451,6 +4476,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_phar___construct, 0, 0, 1)
        ZEND_ARG_INFO(0, filename)
        ZEND_ARG_INFO(0, flags)
        ZEND_ARG_INFO(0, alias)
+       ZEND_ARG_INFO(0, fileformat)
 ZEND_END_ARG_INFO();
 
 static
index 802f6149db764b2963036399f76e2f38a2a3a5f4..6cc395532db662b63540ccb1feefd4e484955988 100644 (file)
@@ -141,6 +141,7 @@ int phar_open_or_create_tar(char *fname, int fname_len, char *alias, int alias_l
 
        if (phar->is_brandnew) {
                phar->is_tar = 1;
+               phar->is_zip = 0;
                phar->internal_file_start = 0;
                return SUCCESS;
        }
@@ -422,6 +423,13 @@ int phar_open_tarfile(php_stream* fp, char *fname, int fname_len, char *alias, i
 #endif
        myphar->fname_len = fname_len;
        p = strrchr(myphar->fname, '/');
+
+       if (zend_hash_exists(&(myphar->manifest), ".phar/stub.php", sizeof(".phar/stub.php")-1)) {
+               myphar->is_data = 0;
+       } else {
+               myphar->is_data = 1;
+       }
+
        if (p) {
                myphar->ext = memchr(p, '.', (myphar->fname + fname_len) - p);
                if (myphar->ext == p) {
index bc6ccaaa78afebc59b3e6d024ecfdb2b65ef4563..0099928f8bea92bcd01f471e38fdb80f63c6aec8 100644 (file)
@@ -1171,9 +1171,14 @@ phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, in
        if (!phar->manifest.arBuckets) {
                return NULL;
        }
+
        if (is_dir) {
+               if (!path_len || path_len == 1) {
+                       return NULL;
+               }
                path_len--;
        }
+
        if (SUCCESS == zend_hash_find(&phar->manifest, path, path_len, (void**)&entry)) {
                if (entry->is_deleted) {
                        /* entry is deleted, but has not been flushed to disk yet */
index d266b53dce89cc9c13e58308aa0be7925133b40a..a82a2aa077f2ec56005fc4627df4313b425f0c7d 100644 (file)
@@ -443,6 +443,13 @@ foundit:
                zend_hash_add(&mydata->manifest, entry.filename, entry.filename_len, (void *)&entry,sizeof(phar_entry_info), NULL);
        }
        mydata->fp = fp;
+
+       if (zend_hash_exists(&(mydata->manifest), ".phar/stub.php", sizeof(".phar/stub.php")-1)) {
+               mydata->is_data = 0;
+       } else {
+               mydata->is_data = 1;
+       }
+
        zend_hash_add(&(PHAR_GLOBALS->phar_fname_map), mydata->fname, fname_len, (void*)&mydata, sizeof(phar_archive_data*), NULL);
        if (actual_alias) {
                phar_archive_data **fd_ptr;
@@ -522,6 +529,7 @@ int phar_open_or_create_zip(char *fname, int fname_len, char *alias, int alias_l
        if (phar->is_brandnew) {
                phar->internal_file_start = 0;
                phar->is_zip = 1;
+               phar->is_tar = 0;
                return SUCCESS;
        }