]> granicus.if.org Git - php/commitdiff
fix weird alias issues, add tests to check for new-found problems
authorGreg Beaver <cellog@php.net>
Mon, 12 May 2008 20:42:07 +0000 (20:42 +0000)
committerGreg Beaver <cellog@php.net>
Mon, 12 May 2008 20:42:07 +0000 (20:42 +0000)
ext/phar/phar.c
ext/phar/phar_object.c
ext/phar/tar.c
ext/phar/tests/alias_acrobatics.phpt [new file with mode: 0644]
ext/phar/tests/phar_setalias2.phpt
ext/phar/tests/tar/alias_acrobatics.phpt [new file with mode: 0644]
ext/phar/tests/zip/033.phpt
ext/phar/tests/zip/alias_acrobatics.phpt [new file with mode: 0644]
ext/phar/tests/zip/badalias.phpt
ext/phar/util.c
ext/phar/zip.c

index 560a9f333b429b4fe3695f9b3e03607ab76f0fd2..ab2cb08ac43f990d5a9daaa77a53d5c1291a7e7f 100644 (file)
@@ -420,10 +420,8 @@ int phar_open_loaded(char *fname, int fname_len, char *alias, int alias_len, int
                if (pphar) {
                        *pphar = NULL;
                }
-               if (phar && alias && (options & REPORT_ERRORS)) {
-                       if (error) {
-                               spprintf(error, 0, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, phar->fname, fname);
-                       }
+               if (phar && error && !(options & REPORT_ERRORS)) {
+                       efree(error);
                }
                return FAILURE;
        }
@@ -984,6 +982,7 @@ int phar_open_file(php_stream *fp, char *fname, int fname_len, char *alias, int
 int phar_open_or_create_filename(char *fname, int fname_len, char *alias, int alias_len, int is_data, int options, phar_archive_data** pphar, char **error TSRMLS_DC) /* {{{ */
 {
        const char *ext_str, *z;
+       char *my_error;
        int ext_len;
        phar_archive_data **test, *unused = NULL;
 
@@ -1005,7 +1004,7 @@ int phar_open_or_create_filename(char *fname, int fname_len, char *alias, int al
        }
 
 check_file:
-       if (phar_open_loaded(fname, fname_len, alias, alias_len, is_data, options, test, 0 TSRMLS_CC) == SUCCESS) {
+       if (phar_open_loaded(fname, fname_len, alias, alias_len, is_data, options, test, &my_error TSRMLS_CC) == SUCCESS) {
                if (pphar) {
                        *pphar = *test;
                }
@@ -1026,6 +1025,13 @@ check_file:
                        (*test)->is_writeable = 1;
                }
                return SUCCESS;
+       } else if (my_error) {
+               if (error) {
+                       *error = my_error;
+               } else {
+                       efree(my_error);
+               }
+               return FAILURE;
        }
 
        if (ext_len > 3 && (z = memchr(ext_str, 'z', ext_len)) && ((ext_str + ext_len) - z >= 2) && !memcmp(z + 1, "ip", 2)) {
@@ -1045,7 +1051,6 @@ check_file:
 int phar_create_or_parse_filename(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 *mydata;
-       int register_alias;
        php_stream *fp;
        char *actual = NULL, *p;
 
@@ -1126,36 +1131,46 @@ int phar_create_or_parse_filename(char *fname, int fname_len, char *alias, int a
        zend_hash_init(&mydata->mounted_dirs, sizeof(char *),
                zend_get_hash_value, NULL, 0);
        mydata->fname_len = fname_len;
-       if (is_data) {
-               alias = NULL;
-               alias_len = 0;
-       } else {
-               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", PHP_PHAR_API_VERSION);
        mydata->is_temporary_alias = alias ? 0 : 1;
        mydata->internal_file_start = -1;
        mydata->fp = NULL;
        mydata->is_writeable = 1;
        mydata->is_brandnew = 1;
-       if (!alias_len || !alias) {
-               /* if we neither have an explicit nor an implicit alias, we use the filename */
+       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 (is_data) {
                alias = NULL;
                alias_len = 0;
-               register_alias = 0;
        } else {
-               register_alias = 1;
+               phar_archive_data **fd_ptr;
+
+               if (alias && SUCCESS == zend_hash_find(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, (void **)&fd_ptr)) {
+                       if (SUCCESS != phar_free_alias(*fd_ptr, alias, alias_len TSRMLS_CC)) {
+                               if (error) {
+                                       spprintf(error, 4096, "phar error: phar \"%s\" cannot set alias \"%s\", already in use by another phar archive", mydata->fname, alias);
+                               }
+                               zend_hash_del(&(PHAR_GLOBALS->phar_fname_map), mydata->fname, fname_len);
+                               if (pphar) {
+                                       *pphar = NULL;
+                               }
+                               return FAILURE;
+                       }
+               }
+               mydata->alias = alias ? estrndup(alias, alias_len) : estrndup(mydata->fname, fname_len);
+               mydata->alias_len = alias ? alias_len : fname_len;
        }
-       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) {
+       if (alias_len && alias) {
                if (FAILURE == zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, (void*)&mydata, sizeof(phar_archive_data*), NULL)) {
                        if (options & REPORT_ERRORS) {
                                if (error) {
                                        spprintf(error, 0, "archive \"%s\" cannot be associated with alias \"%s\", already in use", fname, alias);
                                }
                        }
+                       zend_hash_del(&(PHAR_GLOBALS->phar_fname_map), mydata->fname, fname_len);
+                       if (pphar) {
+                               *pphar = NULL;
+                       }
                        return FAILURE;
                }
        }
index 3b5ae23e0d3d50a9382b9da3576ac2625651a0d9..98b602adbc8b986a30f15b94f919bec1754d974d 100755 (executable)
@@ -1157,6 +1157,9 @@ PHP_METHOD(Phar, __construct)
                        zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
                                "%s", error);
                        efree(error);
+               } else {
+                       zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
+                               "Phar creation or opening failed");
                }
                return;
        }
index a97bbf01252ce4f214de4444eaa42a432c6b11a7..ac19ef3f68c8a31d77082690ba719eb0c8350dfb 100644 (file)
@@ -400,8 +400,8 @@ int phar_open_tarfile(php_stream* fp, char *fname, int fname_len, char *alias, i
                phar_archive_data **fd_ptr;
 
                myphar->is_temporary_alias = 0;
-               if (SUCCESS == zend_hash_find(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, (void **)&fd_ptr)) {
-                       if (SUCCESS != phar_free_alias(*fd_ptr, alias, alias_len TSRMLS_CC)) {
+               if (SUCCESS == zend_hash_find(&(PHAR_GLOBALS->phar_alias_map), actual_alias, myphar->alias_len, (void **)&fd_ptr)) {
+                       if (SUCCESS != phar_free_alias(*fd_ptr, actual_alias, myphar->alias_len TSRMLS_CC)) {
                                if (error) {
                                        spprintf(error, 4096, "phar error: Unable to add tar-based phar \"%s\", alias is already in use", fname);
                                }
@@ -411,8 +411,25 @@ int phar_open_tarfile(php_stream* fp, char *fname, int fname_len, char *alias, i
                }
                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;
+               phar_archive_data **fd_ptr;
+
+               if (alias_len) {
+                       if (SUCCESS == zend_hash_find(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, (void **)&fd_ptr)) {
+                               if (SUCCESS != phar_free_alias(*fd_ptr, alias, alias_len TSRMLS_CC)) {
+                                       if (error) {
+                                               spprintf(error, 4096, "phar error: Unable to add tar-based phar \"%s\", alias is already in use", fname);
+                                       }
+                                       zend_hash_del(&(PHAR_GLOBALS->phar_fname_map), myphar->fname, fname_len);
+                                       return FAILURE;
+                               }
+                       }
+                       zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), actual_alias, myphar->alias_len, (void*)&myphar, sizeof(phar_archive_data*), NULL);
+                       myphar->alias = estrndup(alias, alias_len);
+                       myphar->alias_len = alias_len;
+               } else {
+                       myphar->alias = estrndup(myphar->fname, fname_len);
+                       myphar->alias_len = fname_len;
+               }
                myphar->is_temporary_alias = 1;
        }
        if (pphar) {
diff --git a/ext/phar/tests/alias_acrobatics.phpt b/ext/phar/tests/alias_acrobatics.phpt
new file mode 100644 (file)
index 0000000..1bb20a4
--- /dev/null
@@ -0,0 +1,46 @@
+--TEST--
+Phar: alias edge cases
+--SKIPIF--
+<?php if (!extension_loaded("phar")) die("skip"); ?>
+--INI--
+phar.readonly=0
+--FILE--
+<?php
+
+$fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar';
+$fname2 = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.2.phar';
+
+$p = new Phar($fname);
+
+$p->setAlias('foo');
+$p['unused'] = 'hi';
+try {
+$a = new Phar($fname2, 0, 'foo');
+} catch (Exception $e) {
+echo $e->getMessage(),"\n";
+}
+copy($fname, $fname2);
+echo "2\n";
+try {
+$a = new Phar($fname2);
+} catch (Exception $e) {
+echo $e->getMessage(),"\n";
+}
+try {
+$b = new Phar($fname, 0, 'another');
+} catch (Exception $e) {
+echo $e->getMessage(),"\n";
+}
+?>
+===DONE===
+--CLEAN--
+<?php
+unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar');
+unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.2.phar');
+?>
+--EXPECTF--
+alias "foo" is already used for archive "%salias_acrobatics.phar" cannot be overloaded with "%salias_acrobatics.2.phar"
+2
+Cannot open archive "%salias_acrobatics.2.phar", alias is already in use by existing archive
+alias "another" is already used for archive "%salias_acrobatics.phar" cannot be overloaded with "%salias_acrobatics.phar"
+===DONE===
index df8f42282e3489fc34de73c83a718152fd848f1d..901e4d2ebd5485b142dee307465abd8d6108e539 100644 (file)
@@ -47,5 +47,5 @@ __HALT_COMPILER();
 hio
 test
 alias "test" is already used for archive "%sphar_setalias2.phar.php" and cannot be used for other archives
-archive "%snope.phar" cannot be associated with alias "test", already in use
+alias "test" is already used for archive "%sphar_setalias2.phar.php" cannot be overloaded with "%snope.phar"
 ===DONE===
diff --git a/ext/phar/tests/tar/alias_acrobatics.phpt b/ext/phar/tests/tar/alias_acrobatics.phpt
new file mode 100644 (file)
index 0000000..d08dc04
--- /dev/null
@@ -0,0 +1,46 @@
+--TEST--
+Phar: alias edge cases
+--SKIPIF--
+<?php if (!extension_loaded("phar")) die("skip"); ?>
+--INI--
+phar.readonly=0
+--FILE--
+<?php
+
+$fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.tar';
+$fname2 = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.2.phar.tar';
+
+$p = new Phar($fname);
+
+$p->setAlias('foo');
+$p['unused'] = 'hi';
+try {
+$a = new Phar($fname2, 0, 'foo');
+} catch (Exception $e) {
+echo $e->getMessage(),"\n";
+}
+copy($fname, $fname2);
+echo "2\n";
+try {
+$a = new Phar($fname2);
+} catch (Exception $e) {
+echo $e->getMessage(),"\n";
+}
+try {
+$b = new Phar($fname, 0, 'another');
+} catch (Exception $e) {
+echo $e->getMessage(),"\n";
+}
+?>
+===DONE===
+--CLEAN--
+<?php
+unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar.tar');
+unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.2.phar.tar');
+?>
+--EXPECTF--
+alias "foo" is already used for archive "%salias_acrobatics.phar.tar" cannot be overloaded with "%salias_acrobatics.2.phar.tar"
+2
+phar error: Unable to add tar-based phar "%salias_acrobatics.2.phar.tar", alias is already in use
+alias "another" is already used for archive "%salias_acrobatics.phar.tar" cannot be overloaded with "%salias_acrobatics.phar.tar"
+===DONE===
index 3c1e2de7bc14940c4439d2ceb2a180835eb78ba3..c980758a83a335e692eac97e03a0332eb88aa681 100644 (file)
@@ -22,6 +22,7 @@ try {
        var_dump($phar['a.php']->isExecutable());
        $phar['a.php']->chmod(0777);
        copy($fname, $fname2);
+       $phar->setAlias('unused');
        $phar2 = new Phar($fname2);
        var_dump($phar2['a.php']->isExecutable());
        $phar['a.php']->chmod(0666);
diff --git a/ext/phar/tests/zip/alias_acrobatics.phpt b/ext/phar/tests/zip/alias_acrobatics.phpt
new file mode 100644 (file)
index 0000000..2a58e39
--- /dev/null
@@ -0,0 +1,46 @@
+--TEST--
+Phar: alias edge cases
+--SKIPIF--
+<?php if (!extension_loaded("phar")) die("skip"); ?>
+--INI--
+phar.readonly=0
+--FILE--
+<?php
+
+$fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.zip';
+$fname2 = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.2.phar.zip';
+
+$p = new Phar($fname);
+
+$p->setAlias('foo');
+$p['unused'] = 'hi';
+try {
+$a = new Phar($fname2, 0, 'foo');
+} catch (Exception $e) {
+echo $e->getMessage(),"\n";
+}
+copy($fname, $fname2);
+echo "2\n";
+try {
+$a = new Phar($fname2);
+} catch (Exception $e) {
+echo $e->getMessage(),"\n";
+}
+try {
+$b = new Phar($fname, 0, 'another');
+} catch (Exception $e) {
+echo $e->getMessage(),"\n";
+}
+?>
+===DONE===
+--CLEAN--
+<?php
+unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar.zip');
+unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.2.phar.zip');
+?>
+--EXPECTF--
+alias "foo" is already used for archive "%salias_acrobatics.phar.zip" cannot be overloaded with "%salias_acrobatics.2.phar.zip"
+2
+phar error: Unable to add zip-based phar "%salias_acrobatics.2.phar.zip" with implicit alias, alias is already in use
+alias "another" is already used for archive "%salias_acrobatics.phar.zip" cannot be overloaded with "%salias_acrobatics.phar.zip"
+===DONE===
index 4e08cefd5e160616c09cf5e9fecb5d25d0d4e275..0291c4b0898452e8d92986bf1829bf250b0df6a0 100644 (file)
@@ -17,9 +17,9 @@ echo $ee->getMessage(), "\n";
 ?>
 ===DONE===
 --EXPECTF--
-phar error: invalid alias in zip-based phar "%sbadalias1.phar.zip"
-phar error: invalid alias in zip-based phar "%sbadalias2.phar.zip"
-phar error: invalid alias in zip-based phar "%sbadalias3.phar.zip"
-phar error: invalid alias in zip-based phar "%sbadalias4.phar.zip"
-phar error: invalid alias in zip-based phar "%sbadalias5.phar.zip"
+phar error: invalid alias "hi/there" in zip-based phar "%sbadalias1.phar.zip"
+phar error: invalid alias "hi\there" in zip-based phar "%sbadalias2.phar.zip"
+phar error: invalid alias "hi\there" in zip-based phar "%sbadalias3.phar.zip"
+phar error: invalid alias "hi;there" in zip-based phar "%sbadalias4.phar.zip"
+phar error: invalid alias "hi:there" in zip-based phar "%sbadalias5.phar.zip"
 ===DONE===
index 5bdd018fdfcffbaef32f0a33e9b0bcf9ffe4dcc4..77e83098a42cf14776c2fbdf7c6990e28a38f7af 100644 (file)
@@ -1032,6 +1032,12 @@ int phar_get_archive(phar_archive_data **archive, char *fname, int fname_len, ch
                        *archive = *fd_ptr;
                        fd = *fd_ptr;
                        if (alias && alias_len) {
+                               if (!fd->is_temporary_alias && (alias_len != fd->alias_len || memcmp(fd->alias, alias, alias_len))) {
+                                       if (error) {
+                                               spprintf(error, 0, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, (*fd_ptr)->fname, fname);
+                                       }
+                                       return FAILURE;
+                               }
                                if (fd->alias_len && SUCCESS == zend_hash_find(&(PHAR_GLOBALS->phar_alias_map), fd->alias, fd->alias_len, (void**)&fd_ptr)) {
                                        zend_hash_del(&(PHAR_GLOBALS->phar_alias_map), fd->alias, fd->alias_len);
                                }
index 4b206904678f51d78773f6307869563af9e11821..0261033ff9b95f9fdbf19a1f3aea36709b525396 100644 (file)
@@ -152,7 +152,7 @@ int phar_open_zipfile(php_stream *fp, char *fname, int fname_len, char *alias, i
        php_uint16 i;
        phar_archive_data *mydata = NULL;
        phar_entry_info entry = {0};
-       char *p = buf, *ext;
+       char *p = buf, *ext, *actual_alias = NULL;
 
        size = php_stream_tell(fp);
        if (size > sizeof(locator) + 65536) {
@@ -241,13 +241,6 @@ foundit:
                        mydata->ext_len = (mydata->fname + fname_len) - mydata->ext;
                }
        }
-       if (!alias_len) {
-               mydata->alias = estrndup(fname, fname_len);
-#ifdef PHP_WIN32
-               phar_unixify_path_separators(mydata->alias, fname_len);
-#endif
-               mydata->alias_len = fname_len;
-       }
        /* clean up on big-endian systems */
        /* seek to central directory */
        php_stream_seek(fp, PHAR_GET_32(locator.cdir_offset), SEEK_SET);
@@ -400,15 +393,15 @@ foundit:
                } else {
                        entry.metadata = NULL;
                }
-               if (entry.filename_len == sizeof(".phar/alias.txt")-1 && !strncmp(entry.filename, ".phar/alias.txt", sizeof(".phar/alias.txt")-1)) {
+               if (!actual_alias && entry.filename_len == sizeof(".phar/alias.txt")-1 && !strncmp(entry.filename, ".phar/alias.txt", sizeof(".phar/alias.txt")-1)) {
                        php_stream_filter *filter;
                        off_t saveloc;
-                       phar_archive_data **fd_ptr;
 
                        /* archive alias found, seek to file contents, do not validate local header.  Potentially risky, but
                           not very. */
                        saveloc = php_stream_tell(fp);
                        php_stream_seek(fp, PHAR_GET_32(zipentry.offset) + sizeof(phar_zip_file_header) + entry.filename_len + PHAR_GET_16(zipentry.extra_len), SEEK_SET);
+                       mydata->alias_len = entry.uncompressed_filesize;
                        if (entry.flags & PHAR_ENT_COMPRESSED_GZ) {
                                filter = php_stream_filter_create("zlib.inflate", NULL, php_stream_is_persistent(fp) TSRMLS_CC);
                                if (!filter) {
@@ -416,9 +409,7 @@ foundit:
                                        PHAR_ZIP_FAIL("unable to decompress alias, zlib filter creation failed");
                                }
                                php_stream_filter_append(&fp->readfilters, filter);
-                               efree(mydata->alias);
-                               mydata->alias = NULL;
-                               if (!(entry.uncompressed_filesize = php_stream_copy_to_mem(fp, &(mydata->alias), entry.uncompressed_filesize, 0)) || !mydata->alias) {
+                               if (!(entry.uncompressed_filesize = php_stream_copy_to_mem(fp, &actual_alias, entry.uncompressed_filesize, 0)) || !actual_alias) {
                                        efree(entry.filename);
                                        PHAR_ZIP_FAIL("unable to read in alias, truncated");
                                }
@@ -433,35 +424,19 @@ foundit:
                                }
                                php_stream_filter_append(&fp->readfilters, filter);
                                php_stream_filter_append(&fp->readfilters, filter);
-                               efree(mydata->alias);
-                               mydata->alias = NULL;
-                               if (!(entry.uncompressed_filesize = php_stream_copy_to_mem(fp, &(mydata->alias), entry.uncompressed_filesize, 0)) || !mydata->alias) {
+                               if (!(entry.uncompressed_filesize = php_stream_copy_to_mem(fp, &actual_alias, entry.uncompressed_filesize, 0)) || !actual_alias) {
                                        efree(entry.filename);
                                        PHAR_ZIP_FAIL("unable to read in alias, truncated");
                                }
                                php_stream_filter_flush(filter, 1);
                                php_stream_filter_remove(filter, 1 TSRMLS_CC);
                        } else {
-                               efree(mydata->alias);
-                               mydata->alias = NULL;
-                               if (!(entry.uncompressed_filesize = php_stream_copy_to_mem(fp, &(mydata->alias), entry.uncompressed_filesize, 0)) || !mydata->alias) {
+                               if (!(entry.uncompressed_filesize = php_stream_copy_to_mem(fp, &actual_alias, entry.uncompressed_filesize, 0)) || !actual_alias) {
                                        efree(entry.filename);
                                        PHAR_ZIP_FAIL("unable to read in alias, truncated");
                                }
                        }
 
-                       mydata->is_temporary_alias = 0;
-                       mydata->alias_len = PHAR_GET_32(zipentry.uncompsize);
-                       if (!phar_validate_alias(mydata->alias, mydata->alias_len)) {
-                               efree(entry.filename);
-                               PHAR_ZIP_FAIL("invalid alias");
-                       }
-                       if (SUCCESS == zend_hash_find(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, (void **)&fd_ptr)) {
-                               if (SUCCESS != phar_free_alias(*fd_ptr, alias, alias_len TSRMLS_CC)) {
-                                       PHAR_ZIP_FAIL("alias is already in use by existing archive");
-                               }
-                       }
-                       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 */
                        php_stream_seek(fp, saveloc, SEEK_SET);
                }
@@ -469,6 +444,52 @@ foundit:
        }
        mydata->fp = fp;
        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;
+
+               if (!phar_validate_alias(actual_alias, mydata->alias_len)) {
+                       if (error) {
+                               spprintf(error, 4096, "phar error: invalid alias \"%s\" in zip-based phar \"%s\"", actual_alias, fname);
+                       }
+                       efree(actual_alias);
+                       zend_hash_del(&(PHAR_GLOBALS->phar_fname_map), mydata->fname, fname_len);
+                       return FAILURE;
+               }
+               mydata->is_temporary_alias = 0;
+               if (SUCCESS == zend_hash_find(&(PHAR_GLOBALS->phar_alias_map), actual_alias, mydata->alias_len, (void **)&fd_ptr)) {
+                       if (SUCCESS != phar_free_alias(*fd_ptr, actual_alias, mydata->alias_len TSRMLS_CC)) {
+                               if (error) {
+                                       spprintf(error, 4096, "phar error: Unable to add zip-based phar \"%s\" with implicit alias, alias is already in use", fname);
+                               }
+                               efree(actual_alias);
+                               zend_hash_del(&(PHAR_GLOBALS->phar_fname_map), mydata->fname, fname_len);
+                               return FAILURE;
+                       }
+               }
+               mydata->alias = actual_alias;
+               zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), actual_alias, mydata->alias_len, (void*)&mydata, sizeof(phar_archive_data*), NULL);
+       } else {
+               phar_archive_data **fd_ptr;
+
+               if (alias_len) {
+                       if (SUCCESS == zend_hash_find(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, (void **)&fd_ptr)) {
+                               if (SUCCESS != phar_free_alias(*fd_ptr, alias, alias_len TSRMLS_CC)) {
+                                       if (error) {
+                                               spprintf(error, 4096, "phar error: Unable to add zip-based phar \"%s\" with explicit alias, alias is already in use", fname);
+                                       }
+                                       zend_hash_del(&(PHAR_GLOBALS->phar_fname_map), mydata->fname, fname_len);
+                                       return FAILURE;
+                               }
+                       }
+                       zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), actual_alias, mydata->alias_len, (void*)&mydata, sizeof(phar_archive_data*), NULL);
+                       mydata->alias = estrndup(alias, alias_len);
+                       mydata->alias_len = alias_len;
+               } else {
+                       mydata->alias = estrndup(mydata->fname, fname_len);
+                       mydata->alias_len = fname_len;
+               }
+               mydata->is_temporary_alias = 1;
+       }
        if (pphar) {
                *pphar = mydata;
        }