]> granicus.if.org Git - php/commitdiff
major refactoring of internal handling of aliases.
authorGreg Beaver <cellog@php.net>
Mon, 11 Feb 2008 06:46:44 +0000 (06:46 +0000)
committerGreg Beaver <cellog@php.net>
Mon, 11 Feb 2008 06:46:44 +0000 (06:46 +0000)
1) rename is_explicit_alias to is_temporary_alias for clarity and flip the value
2) fix setAlias so that it sets a permanent to-be-saved alias, and restores the old one on error
3) fix Phar constructor to work with sub-directories in RecursiveDirectoryIterator

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

index 65f476b5f6cc12d15fc5ea64b16e4ef351bdd165..90f1a0ca847afe01803968581b8b5afd1fb4988b 100644 (file)
@@ -498,7 +498,7 @@ int phar_open_file(php_stream *fp, char *fname, int fname_len, char *alias, int
        php_uint32 manifest_len, manifest_count, manifest_flags, manifest_index, tmp_len, sig_flags;
        php_uint16 manifest_ver;
        long offset;
-       int register_alias, sig_len;
+       int register_alias, sig_len, temp_alias = 0;
        char *signature = NULL;
 
        if (pphar) {
@@ -808,8 +808,9 @@ int phar_open_file(php_stream *fp, char *fname, int fname_len, char *alias, int
                alias = NULL;
                alias_len = 0;
                register_alias = 0;
-       } else {
+       } else if (alias_len) {
                register_alias = 1;
+               temp_alias = 1;
        }
        
        /* we have 5 32-bit items plus 1 byte at least */
@@ -929,10 +930,10 @@ int phar_open_file(php_stream *fp, char *fname, int fname_len, char *alias, int
        phar_request_initialize(TSRMLS_C);
        zend_hash_add(&(PHAR_GLOBALS->phar_fname_map), mydata->fname, fname_len, (void*)&mydata, sizeof(phar_archive_data*),  NULL);
        if (register_alias) {
-               mydata->is_explicit_alias = 1;
+               mydata->is_temporary_alias = temp_alias;
                zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, (void*)&mydata, sizeof(phar_archive_data*), NULL);
        } else {
-               mydata->is_explicit_alias = 0;
+               mydata->is_temporary_alias = 1;
        }
        efree(savebuf);
        
@@ -1069,7 +1070,7 @@ int phar_create_or_parse_filename(char *fname, int fname_len, char *alias, int a
        mydata->alias = alias ? estrndup(alias, alias_len) : estrndup(mydata->fname, fname_len);
        mydata->alias_len = alias ? alias_len : fname_len;
        snprintf(mydata->version, sizeof(mydata->version), "%s", PHAR_API_VERSION_STR);
-       mydata->is_explicit_alias = alias ? 1 : 0;
+       mydata->is_temporary_alias = alias ? 0 : 1;
        mydata->internal_file_start = -1;
        mydata->fp = fp;
        mydata->is_writeable = 1;
@@ -1201,7 +1202,7 @@ static int phar_open_fp(php_stream* fp, char *fname, int fname_len, char *alias,
                                array_init(&filterparams);
                                /* ext/zlib zval_dtors a separated zval, so we have to make sure it doesn't destroy ours */
 #if PHP_VERSION_ID < 50300
-                               filterparams->refcount = 26;
+                               filterparams.refcount = 26;
 #else
                                Z_SET_REFCOUNT(filterparams, 26);
 #endif
@@ -2082,7 +2083,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, long len, char **error
         *  ?: phar metadata
         */
        restore_alias_len = phar->alias_len;
-       if (!phar->is_explicit_alias) {
+       if (phar->is_temporary_alias) {
                phar->alias_len = 0;
        }
 
index 3e28299ec8d0bf448bf975efe584b7ceb02ad1a6..57a5ec1de6bdc35d5b5cd69e3cf272200c0446ca 100755 (executable)
@@ -265,7 +265,8 @@ struct _phar_archive_data {
        int                      sig_len;
        char                     *signature;
        zval                     *metadata;
-       int                      is_explicit_alias:1;
+       /* if 1, then this alias was manually specified by the user and is not a permanent alias */
+       int                      is_temporary_alias:1;
        int                      is_modified:1;
        int                      is_writeable:1;
        int                      is_brandnew:1;
index 9e92f1f0cc478840f98d56cd2e08fbabeb21bb82..4a768390fd7b4c0fc16b3c646fa6465936a7932a 100755 (executable)
@@ -1046,8 +1046,8 @@ PHP_METHOD(Phar, __construct)
 #if !HAVE_SPL
        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;
-       int fname_len, alias_len = 0;
+       char *fname, *alias = NULL, *error, *arch, *entry = NULL, *save_fname;
+       int fname_len, alias_len = 0, arch_len, entry_len;
        long flags = 0;
        phar_archive_object *phar_obj;
        phar_archive_data   *phar_data;
@@ -1064,23 +1064,45 @@ PHP_METHOD(Phar, __construct)
                return;
        }
 
+       if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len)) {
+               /* use arch for fname instead of fname */
+               /* this allows support for RecursiveDirectoryIterator of subdirectories */
+               save_fname = fname;
+               fname = arch;
+               fname_len = arch_len;
+       }
        if (phar_open_or_create_filename(fname, fname_len, alias, alias_len, REPORT_ERRORS, &phar_data, &error TSRMLS_CC) == FAILURE) {
+               if (fname == arch) {
+                       efree(arch);
+                       fname = save_fname;
+               }
                if (error) {
+                       efree(entry);
                        zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
                                "Cannot open phar file '%s' with alias '%s': %s", fname, alias, error);
                        efree(error);
                } else {
+                       efree(entry);
                        zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
                                "Cannot open phar file '%s' with alias '%s'", fname, alias);
                }
                return;
        }
 
+       if (fname == arch) {
+               efree(arch);
+               fname = save_fname;
+       }
        phar_data->refcount++;
        phar_obj->arc.archive = phar_data;
        phar_obj->spl.oth_handler = &phar_spl_foreign_handler;
 
-       fname_len = spprintf(&fname, 0, "phar://%s", phar_data->fname);
+       if (entry) {
+               fname_len = spprintf(&fname, 0, "phar://%s%s", phar_data->fname, entry);
+               efree(entry);
+       } else {
+               fname_len = spprintf(&fname, 0, "phar://%s", phar_data->fname);
+       }
        INIT_PZVAL(&arg1);
        ZVAL_STRINGL(&arg1, fname, fname_len, 0);
 
@@ -1976,9 +1998,9 @@ PHP_METHOD(Phar, getAlias)
  */
 PHP_METHOD(Phar, setAlias)
 {
-       char *alias, *error;
+       char *alias, *error, *oldalias;
        phar_archive_data **fd_ptr;
-       int alias_len;
+       int alias_len, oldalias_len, old_temp, readd = 0;
        PHAR_ARCHIVE_OBJECT();
 
        if (PHAR_G(readonly)) {
@@ -1999,23 +2021,35 @@ PHP_METHOD(Phar, setAlias)
                }
                if (phar_obj->arc.archive->alias_len && SUCCESS == zend_hash_find(&(PHAR_GLOBALS->phar_alias_map), phar_obj->arc.archive->alias, phar_obj->arc.archive->alias_len, (void**)&fd_ptr)) {
                        zend_hash_del(&(PHAR_GLOBALS->phar_alias_map), phar_obj->arc.archive->alias, phar_obj->arc.archive->alias_len);
+                       readd = 1;
                }
 
-               if (phar_obj->arc.archive->alias) {
-                       efree(phar_obj->arc.archive->alias);
-               }
+               oldalias = phar_obj->arc.archive->alias;
+               oldalias_len = phar_obj->arc.archive->alias_len;
+               old_temp = phar_obj->arc.archive->is_temporary_alias;
                if (alias_len) {
                        phar_obj->arc.archive->alias = estrndup(alias, alias_len);
                } else {
                        phar_obj->arc.archive->alias = NULL;
                }
                phar_obj->arc.archive->alias_len = alias_len;
-               phar_obj->arc.archive->is_explicit_alias = 1;
+               phar_obj->arc.archive->is_temporary_alias = 0;
 
                phar_flush(phar_obj->arc.archive, NULL, 0, &error TSRMLS_CC);
                if (error) {
+                       phar_obj->arc.archive->alias = oldalias;
+                       phar_obj->arc.archive->alias_len = oldalias_len;
+                       phar_obj->arc.archive->is_temporary_alias = old_temp;
                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, error);
+                       if (readd) {
+                               zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), oldalias, oldalias_len, (void*)&(phar_obj->arc.archive), sizeof(phar_archive_data*), NULL);
+                       }
                        efree(error);
+                       return;
+               }
+               zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, (void*)&(phar_obj->arc.archive), sizeof(phar_archive_data*), NULL);
+               if (oldalias) {
+                       efree(oldalias);
                }
                RETURN_TRUE;
        }
index 30d962615fb83d4beceaf22ef78db6585fa9f2a5..78f4d1b8e323b4652898a94a4a3133ff7bd700e6 100644 (file)
@@ -312,12 +312,12 @@ int phar_open_tarfile(php_stream* fp, char *fname, int fname_len, char *alias, i
        }
        myphar = *actual;
        if (actual_alias) {
-               myphar->is_explicit_alias = 1;
+               myphar->is_temporary_alias = 0;
                zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), actual_alias, myphar->alias_len, (void*)&myphar, sizeof(phar_archive_data*), NULL);
        } else {
                myphar->alias = estrndup(myphar->fname, fname_len);
                myphar->alias_len = fname_len;
-               myphar->is_explicit_alias = 0;
+               myphar->is_temporary_alias = 1;
        }
        if (pphar) {
                *pphar = myphar;
@@ -448,14 +448,26 @@ int phar_tar_flush(phar_archive_data *phar, char *user_stub, long len, char **er
        entry.phar = phar;
        entry.fp_type = PHAR_MOD;
        /* set alias */
-       if (phar->is_explicit_alias) {
+       if (!phar->is_temporary_alias && phar->alias_len) {
                entry.filename = estrndup(".phar/alias.txt", sizeof(".phar/alias.txt")-1);
                entry.filename_len = sizeof(".phar/alias.txt")-1;
                entry.fp = php_stream_fopen_tmpfile();
                entry.crc32 = phar_tar_checksum(phar->alias, phar->alias_len);
-               php_stream_write(entry.fp, phar->alias, phar->alias_len);
+               if (phar->alias_len != (int)php_stream_write(entry.fp, phar->alias, phar->alias_len)) {
+                       if (error) {
+                               spprintf(error, 0, "unable to set alias in tar-based phar \"%s\"", phar->fname);
+                       }
+                       return EOF;
+               }
                entry.uncompressed_filesize = phar->alias_len;
-               zend_hash_update(&phar->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info), NULL);
+               if (SUCCESS != zend_hash_update(&phar->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info), NULL)) {
+                       if (error) {
+                               spprintf(error, 0, "unable to set alias in tar-based phar \"%s\"", phar->fname);
+                       }
+                       return EOF;
+               }
+       } else {
+               zend_hash_del(&phar->manifest, ".phar/alias.txt", sizeof(".phar/alias.txt")-1);
        }
 
        /* set stub */
index 5fc548ebf28063f255b9bfdd9869ef5619044bd3..2626a34cd9d05d0ebd62f20c2c522246ff687450 100644 (file)
@@ -350,7 +350,7 @@ foundit:
                                }
                        }
 
-                       mydata->is_explicit_alias = 1;
+                       mydata->is_temporary_alias = 0;
                        mydata->alias_len = zipentry.uncompsize;
                        zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), mydata->alias, mydata->alias_len, (void*)&mydata, sizeof(phar_archive_data*), NULL);
                        /* return to central directory parsing */
@@ -659,11 +659,11 @@ int phar_zip_flush(phar_archive_data *phar, char *user_stub, long len, char **er
        entry.fp_type = PHAR_MOD;
 
        /* set alias */
-       if (phar->is_explicit_alias) {
+       if (!phar->is_temporary_alias && phar->alias_len) {
                entry.fp = php_stream_fopen_tmpfile();
                if (phar->alias_len != (int)php_stream_write(entry.fp, phar->alias, phar->alias_len)) {
                        if (error) {
-                               spprintf(error, 0, "unable to set alias in new zip-based phar \"%s\"", phar->fname);
+                               spprintf(error, 0, "unable to set alias in zip-based phar \"%s\"", phar->fname);
                        }
                        return EOF;
                }
@@ -673,10 +673,12 @@ int phar_zip_flush(phar_archive_data *phar, char *user_stub, long len, char **er
                entry.is_modified = 1;
                if (SUCCESS != zend_hash_update(&phar->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info), NULL)) {
                        if (error) {
-                               spprintf(error, 0, "unable to set alias in new zip-based phar \"%s\"", phar->fname);
+                               spprintf(error, 0, "unable to set alias in zip-based phar \"%s\"", phar->fname);
                        }
                        return EOF;
                }
+       } else {
+               zend_hash_del(&phar->manifest, ".phar/alias.txt", sizeof(".phar/alias.txt")-1);
        }
        /* register alias */
        if (phar->alias_len) {