]> granicus.if.org Git - php/commitdiff
eliminate potential double-free of alias
authorGreg Beaver <cellog@php.net>
Mon, 7 Jan 2008 22:21:10 +0000 (22:21 +0000)
committerGreg Beaver <cellog@php.net>
Mon, 7 Jan 2008 22:21:10 +0000 (22:21 +0000)
major improvement of zip/tar-based phar stub execution, now __FILE__ says it is the phar, and not phar/.phar/stub.php,
so that the same stub can be used for phar or tar/zip-based phars
ridiculous speedup of rename() within a phar (something like 1000%)
last of the tar-based phar fixes
new tests for tar-based phars, fix existing tests to use new format of __FILE__

20 files changed:
ext/phar/phar.c
ext/phar/phar_object.c
ext/phar/tar.c
ext/phar/tests/tar/frontcontroller10.phar.phpt
ext/phar/tests/tar/frontcontroller11.phar.phpt
ext/phar/tests/tar/frontcontroller12.phar.phpt
ext/phar/tests/tar/frontcontroller13.phar.phpt
ext/phar/tests/tar/frontcontroller18.phar.phpt
ext/phar/tests/tar/frontcontroller19.phar.phpt
ext/phar/tests/tar/frontcontroller20.phar.phpt
ext/phar/tests/tar/phar_commitwrite.phpt [new file with mode: 0644]
ext/phar/tests/tar/phar_copy.phpt [new file with mode: 0644]
ext/phar/tests/tar/phar_magic.phpt [new file with mode: 0644]
ext/phar/tests/tar/phar_setalias.phpt [new file with mode: 0644]
ext/phar/tests/tar/phar_setalias2.phpt [new file with mode: 0644]
ext/phar/tests/tar/phar_stub_error.phpt [new file with mode: 0755]
ext/phar/tests/tar/refcount1.phpt [new file with mode: 0644]
ext/phar/tests/tar/refcount1_5_2.phpt [new file with mode: 0755]
ext/phar/tests/tar/rename.phpt [new file with mode: 0644]
ext/phar/tests/tar/tar_004.phpt

index 046a5be406248c1f14e30020e0326e752b0a1ee7..0a0568f3125dbc0ae7f984823a14842186fc3b19 100644 (file)
@@ -218,6 +218,7 @@ static void phar_destroy_phar_data(phar_archive_data *data TSRMLS_DC) /* {{{ */
        }
        if (data->fname) {
                efree(data->fname);
+               data->fname = NULL;
        }
        if (data->signature) {
                efree(data->signature);
@@ -1070,7 +1071,7 @@ int phar_open_zipfile(char *fname, int fname_len, char *alias, int alias_len, ph
        } else {
                register_alias = alias ? 1 : 0;
        }
-       mydata->alias = alias ? estrndup(alias, alias_len) : mydata->fname;
+       mydata->alias = alias ? estrndup(alias, alias_len) : estrndup(mydata->fname, alias_len);
        mydata->alias_len = alias ? alias_len : fname_len;
        mydata->is_zip = 1;
        mydata->zip = zip;
@@ -1175,7 +1176,7 @@ int phar_open_zipfile(char *fname, int fname_len, char *alias, int alias_len, ph
        /* ignore all errors in loading up manifest */
        zip_error_clear(zip);
 
-       zend_hash_add(&(PHAR_GLOBALS->phar_fname_map), mydata->fname, fname_len, (void*)&mydata, sizeof(phar_archive_data*), NULL);
+       zend_hash_add(&(PHAR_GLOBALS->phar_fname_map), fname, fname_len, (void*)&mydata, sizeof(phar_archive_data*), NULL);
        if (register_alias) {
                mydata->is_explicit_alias = 1;
                zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, (void*)&mydata, sizeof(phar_archive_data*), NULL);
@@ -1635,7 +1636,7 @@ int phar_open_file(php_stream *fp, char *fname, int fname_len, char *alias, int
        phar_unixify_path_separators(mydata->fname, fname_len);
 #endif
        mydata->fname_len = fname_len;
-       mydata->alias = alias ? estrndup(alias, alias_len) : mydata->fname;
+       mydata->alias = alias ? estrndup(alias, alias_len) : estrndup(fname, fname_len);
        mydata->alias_len = alias ? alias_len : fname_len;
        mydata->sig_flags = sig_flags;
        mydata->sig_len = sig_len;
@@ -1834,7 +1835,7 @@ int phar_create_or_parse_filename(char *fname, int fname_len, char *alias, int a
 #endif
        }
        mydata->fname_len = fname_len;
-       mydata->alias = alias ? estrndup(alias, alias_len) : mydata->fname;
+       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;
@@ -2313,36 +2314,6 @@ 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 (strstr(fname, "phar://") && strstr(fname, ".phar/stub.php")) {
-               char *arch, *entry;
-               int arch_len, entry_len;
-               phar_archive_data *phar;
-
-               if (SUCCESS != phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len TSRMLS_CC)) {
-                       efree(entry);
-                       efree(arch);
-                       goto regular_error;
-               }
-               if (strcmp(entry, "/.phar/stub.php")) {
-                       efree(entry);
-                       efree(arch);
-                       goto regular_error;
-               }
-
-               /* we're running from inside a zip-based phar */
-               efree(entry);
-               entry = fname;
-               fname = arch;
-               fname_len = arch_len;
-               if (SUCCESS == phar_open_loaded(fname, fname_len, alias, alias_len, 0, &phar, 0 TSRMLS_CC) && phar && (phar->is_zip || phar->is_tar)) {
-                       efree(arch);
-                       return SUCCESS;
-               }
-               /* restore original value for error purpose */
-               fname = entry;
-       }
-regular_error:
-
        if (phar_open_loaded(fname, fname_len, alias, alias_len, REPORT_ERRORS, NULL, 0 TSRMLS_CC) == SUCCESS) {
                return SUCCESS;
        }
@@ -4444,10 +4415,12 @@ static int phar_wrapper_unlink(php_stream_wrapper *wrapper, char *url, int optio
 static int phar_wrapper_rename(php_stream_wrapper *wrapper, char *url_from, char *url_to, int options, php_stream_context *context TSRMLS_DC) /* {{{ */
 {
        php_url *resource_from, *resource_to;
-       char *from_file, *to_file, *error, *plain_map;
-       phar_entry_data *fromdata, *todata;
+       char *error, *plain_map;
+       phar_archive_data *phar;
+       phar_entry_info *entry;
        uint host_len;
 
+       error = NULL;
        if (PHAR_G(readonly)) {
                php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: write operations disabled by INI setting");
                return 0;
@@ -4502,102 +4475,66 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, char *url_from, char
        phar_request_initialize(TSRMLS_C);
        if (zend_hash_find(&(PHAR_GLOBALS->phar_plain_map), resource_from->host, host_len+1, (void **)&plain_map) == SUCCESS) {
                /*TODO:use php_stream_rename() once available*/
+               php_url_free(resource_from);
+               php_url_free(resource_to);
                php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: cannot rename \"%s\" to \"%s\" from extracted phar archive", url_from, url_to);
                return 0;
        }
 
-       /* need to copy to strip leading "/", will get touched again */
-       from_file = estrdup(resource_from->path + 1);
-       to_file = estrdup(resource_to->path + 1);
-       if (FAILURE == phar_get_entry_data(&fromdata, resource_from->host, strlen(resource_from->host), from_file, strlen(from_file), "r", &error TSRMLS_CC)) {
-               /* constraints of fp refcount were not met */
-               if (error) {
-                       php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, error);
-                       efree(error);
-               }
-               efree(from_file);
-               efree(to_file);
+       if (SUCCESS != phar_get_archive(&phar, resource_from->host, strlen(resource_from->host), NULL, 0, &error TSRMLS_CC)) {
                php_url_free(resource_from);
                php_url_free(resource_to);
-               return 0;
-       }
-       if (error) {
+               php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: cannot rename \"%s\" to \"%s\": %s", url_from, url_to, error);
                efree(error);
-       }
-       if (!fromdata) {
-               php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: \"%s\" is not a file in phar \"%s\", cannot rename", from_file, resource_from->host);
-               efree(from_file);
-               efree(to_file);
-               php_url_free(resource_from);
-               php_url_free(resource_to);
                return 0;
        }
-       if (!(todata = phar_get_or_create_entry_data(resource_to->host, strlen(resource_to->host), to_file, strlen(to_file), "w", &error TSRMLS_CC))) {
-               /* constraints of fp refcount were not met */
+
+       if (SUCCESS == zend_hash_find(&(phar->manifest), resource_from->path+1, strlen(resource_from->path)-1, (void **)&entry)) {
+               phar_entry_info new;
+
+               /* perform rename magic */
+               if (entry->is_deleted) {
+                       php_url_free(resource_from);
+                       php_url_free(resource_to);
+                       php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: cannot rename \"%s\" to \"%s\" from extracted phar archive, source has been deleted", url_from, url_to);
+                       return 0;
+               }
+               /* transfer all data over to the new entry */
+               memcpy((void *) &new, (void *) entry, sizeof(phar_entry_info));
+               /* mark the old one for deletion */
+               entry->is_deleted = 1;
+               entry->fp = NULL;
+               entry->metadata = 0;
+               entry->link = NULL;
+#if HAVE_ZIP
+               entry->zip = NULL;
+#endif
+
+               zend_hash_add(&(phar->manifest), resource_to->path+1, strlen(resource_to->path)-1, (void **)&new, sizeof(phar_entry_info), (void **) &entry);
+               if (!entry->is_modified) {
+                       /* copy file contents into a new temp stream */
+                       if (!phar_open_jit(phar, entry, phar->fp, &error, 1 TSRMLS_CC)) {
+                               php_url_free(resource_from);
+                               php_url_free(resource_to);
+                               php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: cannot rename \"%s\" to \"%s\": %s", url_from, url_to, error);
+                               efree(error);
+                               return 0;
+                       }
+               }
+               entry->is_modified = 1;
+               entry->filename = estrdup(resource_to->path+1);
+               entry->filename_len = strlen(entry->filename);
+               phar_flush(phar, 0, 0, &error TSRMLS_CC);
                if (error) {
-                       php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, error);
+                       php_url_free(resource_from);
+                       php_url_free(resource_to);
+                       php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: cannot rename \"%s\" to \"%s\": %s", url_from, url_to, error);
                        efree(error);
+                       return 0;
                }
-               efree(from_file);
-               efree(to_file);
-               php_url_free(resource_from);
-               php_url_free(resource_to);
-               return 0;
-       }
-       if (error) {
-               efree(error);
-       }
-       if (fromdata->internal_file->fp_refcount > 1) {
-               /* more than just our fp resource is open for this file */ 
-               php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: \"%s\" in phar \"%s\", has open file pointers, cannot rename", from_file, resource_from->host);
-               efree(from_file);
-               efree(to_file);
-               php_url_free(resource_from);
-               php_url_free(resource_to);
-               phar_entry_delref(fromdata TSRMLS_CC);
-               phar_entry_delref(todata TSRMLS_CC);
-               return 0;
        }
-       if (todata->internal_file->fp_refcount > 1) {
-               /* more than just our fp resource is open for this file */ 
-               php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: \"%s\" in phar \"%s\", has open file pointers, cannot rename", to_file, resource_to->host);
-               efree(from_file);
-               efree(to_file);
-               php_url_free(resource_from);
-               php_url_free(resource_to);
-               phar_entry_delref(fromdata TSRMLS_CC);
-               phar_entry_delref(todata TSRMLS_CC);
-               return 0;
-       }
-
-       php_stream_seek(fromdata->internal_file->fp, 0 + fromdata->zero, SEEK_SET);
-       if (fromdata->internal_file->uncompressed_filesize != php_stream_copy_to_stream(fromdata->internal_file->fp, todata->internal_file->fp, PHP_STREAM_COPY_ALL)) {
-               php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: rename failed \"%s\" to \"%s\"", url_from, url_to);
-               efree(from_file);
-               efree(to_file);
-               php_url_free(resource_from);
-               php_url_free(resource_to);
-               phar_entry_delref(fromdata TSRMLS_CC);
-               phar_entry_delref(todata TSRMLS_CC);
-               return 0;
-       }
-       todata->internal_file->uncompressed_filesize = todata->internal_file->compressed_filesize = fromdata->internal_file->uncompressed_filesize;
-       phar_entry_delref(fromdata TSRMLS_CC);
-       phar_entry_delref(todata TSRMLS_CC);
-       if (error) {
-               php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, error);
-               efree(error);
-               efree(from_file);
-               efree(to_file);
-               php_url_free(resource_from);
-               php_url_free(resource_to);
-               return 0;
-       }
-       efree(from_file);
-       efree(to_file);
        php_url_free(resource_from);
        php_url_free(resource_to);
-       phar_wrapper_unlink(wrapper, url_from, 0, 0 TSRMLS_CC);
        return 1;
 }
 /* }}} */
@@ -4743,13 +4680,18 @@ static zend_op_array *phar_compile_file(zend_file_handle *file_handle, int type
        if (strstr(file_handle->filename, ".phar") && !strstr(file_handle->filename, ":\\")) {
                if (SUCCESS == phar_open_filename(file_handle->filename, strlen(file_handle->filename), NULL, 0, 0, &phar, NULL TSRMLS_CC)) {
                        if (phar->is_zip || phar->is_tar) {
-                               /* zip-based phar */
+                               zend_file_handle f = *file_handle;
+
+                               /* zip or tar-based phar */
                                spprintf(&name, 4096, "phar://%s/%s", file_handle->filename, ".phar/stub.php");
-                               file_handle->type = ZEND_HANDLE_FILENAME;
-                               file_handle->free_filename = 1;
-                               file_handle->filename = name;
-                               if (file_handle->opened_path) {
-                                       efree(file_handle->opened_path);
+                               if (SUCCESS == zend_stream_open_function((const char *)name, file_handle TSRMLS_CC)) {
+                                       efree(name);
+                                       name = NULL;
+                                       file_handle->filename = f.filename;
+                                       file_handle->opened_path = f.opened_path;
+                                       file_handle->free_filename = f.free_filename;
+                               } else {
+                                       *file_handle = f;
                                }
                                goto skip_phar;
                        }
@@ -4774,6 +4716,10 @@ static zend_op_array *phar_compile_file(zend_file_handle *file_handle, int type
                        /* auto-convert to phar:// */
                        spprintf(&name, 4096, "phar://%s/%s", arch, entry);
                        efree(arch);
+                       if (file_handle->type == ZEND_HANDLE_FP) {
+                               // clean up
+                               fclose(file_handle->handle.fp);
+                       }
                        file_handle->type = ZEND_HANDLE_FILENAME;
                        file_handle->free_filename = 1;
                        file_handle->filename = name;
index 4f7d9c8dc2155482d6a9f1e7cc3fe4f2c77dbe20..7e9229130c101348dbdc3854e220fbba00dc6129 100755 (executable)
@@ -379,31 +379,6 @@ PHP_METHOD(Phar, webPhar)
        fname = zend_get_executed_filename(TSRMLS_C);
        fname_len = strlen(fname);
 
-       if (strstr(fname, "://")) {
-               char *arch, *entry;
-               int arch_len, entry_len;
-               phar_archive_data *mphar;
-
-               /* running within a zip-based phar, acquire the actual name */
-               if (SUCCESS != phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len TSRMLS_CC)) {
-                       efree(entry);
-                       efree(arch);
-                       return; /* this, incidentally, should be impossible */
-               }
-
-               efree(entry);
-               entry = fname;
-               fname = arch;
-               fname_len = arch_len;
-               if (SUCCESS == phar_open_loaded(fname, fname_len, alias, alias_len, 0, &mphar, 0 TSRMLS_CC) && mphar && (mphar->is_zip || mphar->is_tar)) {
-                       efree(arch);
-                       fname = mphar->fname;
-                       fname_len = mphar->fname_len;
-               } else {
-                       efree(arch);
-                       fname = entry;
-               }
-       }
 #ifdef PHP_WIN32
        fname = estrndup(fname, fname_len);
        phar_unixify_path_separators(fname, fname_len);
index 9bd8d4f5f7f33b0547670c92dcfd4cc51cb8e50f..3a5b6cbf971a9a771728690c510e660d689fe173 100644 (file)
@@ -156,7 +156,7 @@ int phar_open_tarfile(php_stream* fp, char *fname, int fname_len, char *alias, i
        size_t pos = 0, read;
        tar_header *hdr;
        php_uint32 sum1, sum2, size, old;
-       phar_archive_data *myphar;
+       phar_archive_data *myphar, **retdata;
 
        if (error) {
                *error = NULL;
@@ -283,11 +283,13 @@ int phar_open_tarfile(php_stream* fp, char *fname, int fname_len, char *alias, i
        myphar->fname_len = fname_len;
        myphar->fp = fp;
        phar_request_initialize(TSRMLS_C);
-       zend_hash_add(&(PHAR_GLOBALS->phar_fname_map), myphar->fname, fname_len, (void*)&myphar, sizeof(phar_archive_data*),  NULL);
+       zend_hash_add(&(PHAR_GLOBALS->phar_fname_map), fname, fname_len, (void*)&myphar, sizeof(phar_archive_data*), NULL);
        if (actual_alias) {
                myphar->is_explicit_alias = 1;
                zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), actual_alias, myphar->alias_len, (void*)&myphar, sizeof(phar_archive_data*), NULL);
        } else {
+               myphar->alias = estrndup(fname, fname_len);
+               myphar->alias_len = fname_len;
                myphar->is_explicit_alias = 0;
        }
        if (pphar) {
@@ -415,6 +417,7 @@ int phar_tar_flush(phar_archive_data *archive, char *user_stub, long len, char *
        entry.flags = PHAR_ENT_PERM_DEF_FILE;
        entry.timestamp = time(NULL);
        entry.is_modified = 1;
+       entry.is_crc_checked = 1;
        entry.is_tar = 1;
        entry.tar_type = '0';
        entry.phar = archive;
index 720fe00766006c2baa1a1a9496d3958bdb056ac7..f6b52b0496089944880792b7a95314e692317fa5 100644 (file)
@@ -10,8 +10,8 @@ frontcontroller4.phar.tar
 --EXPECTHEADERS--
 Content-type: text/html
 --EXPECTF--
-Fatal error: Uncaught exception 'UnexpectedValueException' with message 'phar rewrite value for "/hi" was not a string' in %sfrontcontroller10.phar.php/.phar/stub.php:2
+Fatal error: Uncaught exception 'UnexpectedValueException' with message 'phar rewrite value for "/hi" was not a string' in %sfrontcontroller10.phar.php:2
 Stack trace:
-#0 %sfrontcontroller10.phar.php/.phar/stub.php(2): Phar::webPhar('whatever', 'index.php', '', Array, Array)
+#0 %sfrontcontroller10.phar.php(2): Phar::webPhar('whatever', 'index.php', '', Array, Array)
 #1 {main}
-  thrown in %sfrontcontroller10.phar.php/.phar/stub.php on line 2
\ No newline at end of file
+  thrown in %sfrontcontroller10.phar.php on line 2
\ No newline at end of file
index a050b1f7f95d3653f5e409b8968235eea35b1884..be66fd18d2ef30631ff07e35a037b86d8ba49091 100644 (file)
@@ -10,8 +10,8 @@ frontcontroller5.phar.tar
 --EXPECTHEADERS--
 Content-type: text/html
 --EXPECTF--
-Fatal error: Uncaught exception 'UnexpectedValueException' with message 'Key of MIME type overrides array must be a file extension, was "0"' in %sfrontcontroller11.phar.php/.phar/stub.php:2
+Fatal error: Uncaught exception 'UnexpectedValueException' with message 'Key of MIME type overrides array must be a file extension, was "0"' in %sfrontcontroller11.phar.php:2
 Stack trace:
-#0 %sfrontcontroller11.phar.php/.phar/stub.php(2): Phar::webPhar('whatever', 'index.php', '', Array)
+#0 %sfrontcontroller11.phar.php(2): Phar::webPhar('whatever', 'index.php', '', Array)
 #1 {main}
-  thrown in %sfrontcontroller11.phar.php/.phar/stub.php on line 2
\ No newline at end of file
+  thrown in %sfrontcontroller11.phar.php on line 2
\ No newline at end of file
index 192e613e24e7a827ed374b2f99d7245fb581140f..74271301914f50a7c06379dd4408dad425a74865 100644 (file)
@@ -10,8 +10,8 @@ frontcontroller6.phar.tar
 --EXPECTHEADERS--
 Content-type: text/html
 --EXPECTF--
-Fatal error: Uncaught exception 'UnexpectedValueException' with message 'Unknown mime type specifier used, only Phar::PHP, Phar::PHPS and a mime type string are allowed' in %sfrontcontroller12.phar.php/.phar/stub.php:2
+Fatal error: Uncaught exception 'UnexpectedValueException' with message 'Unknown mime type specifier used, only Phar::PHP, Phar::PHPS and a mime type string are allowed' in %sfrontcontroller12.phar.php:2
 Stack trace:
-#0 %sfrontcontroller12.phar.php/.phar/stub.php(2): Phar::webPhar('whatever', 'index.php', '', Array)
+#0 %sfrontcontroller12.phar.php(2): Phar::webPhar('whatever', 'index.php', '', Array)
 #1 {main}
-  thrown in %sfrontcontroller12.phar.php/.phar/stub.php on line 2
\ No newline at end of file
+  thrown in %sfrontcontroller12.phar.php on line 2
\ No newline at end of file
index ad3b9fc27948fd14927992249a6f6066d9929576..6b2b4f355117a6991f8b2ac59056ada558c04113 100644 (file)
@@ -10,8 +10,8 @@ frontcontroller7.phar.tar
 --EXPECTHEADERS--
 Content-type: text/html
 --EXPECTF--
-Fatal error: Uncaught exception 'UnexpectedValueException' with message 'Unknown mime type specifier used (not a string or int), only Phar::PHP, Phar::PHPS and a mime type string are allowed' in %sfrontcontroller13.phar.php/.phar/stub.php:2
+Fatal error: Uncaught exception 'UnexpectedValueException' with message 'Unknown mime type specifier used (not a string or int), only Phar::PHP, Phar::PHPS and a mime type string are allowed' in %sfrontcontroller13.phar.php:2
 Stack trace:
-#0 %sfrontcontroller13.phar.php/.phar/stub.php(2): Phar::webPhar('whatever', 'index.php', '', Array)
+#0 %sfrontcontroller13.phar.php(2): Phar::webPhar('whatever', 'index.php', '', Array)
 #1 {main}
-  thrown in %sfrontcontroller13.phar.php/.phar/stub.php on line 2
\ No newline at end of file
+  thrown in %sfrontcontroller13.phar.php on line 2
\ No newline at end of file
index 1df42d54719bf7c64fb67b92817626082601def0..3d6f8c85aa388b314292d10e583d356e11ecca3d 100644 (file)
@@ -8,8 +8,8 @@ REQUEST_URI=/frontcontroller18.phar.php/fronk.gronk
 --FILE_EXTERNAL--
 frontcontroller9.phar.tar
 --EXPECTF--
-Fatal error: Uncaught exception 'UnexpectedValueException' with message 'No values passed to Phar::mungServer(), expecting an array of any of these strings: PHP_SELF, REQUEST_URI, SCRIPT_FILENAME, SCRIPT_NAME' in %sfrontcontroller18.phar.php/.phar/stub.php:2
+Fatal error: Uncaught exception 'UnexpectedValueException' with message 'No values passed to Phar::mungServer(), expecting an array of any of these strings: PHP_SELF, REQUEST_URI, SCRIPT_FILENAME, SCRIPT_NAME' in %sfrontcontroller18.phar.php:2
 Stack trace:
-#0 %sfrontcontroller18.phar.php/.phar/stub.php(2): Phar::mungServer(Array)
+#0 %sfrontcontroller18.phar.php(2): Phar::mungServer(Array)
 #1 {main}
-  thrown in %sfrontcontroller18.phar.php/.phar/stub.php on line 2
+  thrown in %sfrontcontroller18.phar.php on line 2
index a704a5e38bfb1350f1d84657c4b1eced017d42f4..df5094b9d926a12ac1b159f0281a5fc2e7a1c201 100644 (file)
@@ -8,8 +8,8 @@ REQUEST_URI=/frontcontroller19.phar.php/
 --FILE_EXTERNAL--
 frontcontroller10.phar.tar
 --EXPECTF--
-Fatal error: Uncaught exception 'UnexpectedValueException' with message 'Too many values passed to Phar::mungServer(), expecting an array of any of these strings: PHP_SELF, REQUEST_URI, SCRIPT_FILENAME, SCRIPT_NAME' in %sfrontcontroller19.phar.php/.phar/stub.php:2
+Fatal error: Uncaught exception 'UnexpectedValueException' with message 'Too many values passed to Phar::mungServer(), expecting an array of any of these strings: PHP_SELF, REQUEST_URI, SCRIPT_FILENAME, SCRIPT_NAME' in %sfrontcontroller19.phar.php:2
 Stack trace:
-#0 %sfrontcontroller19.phar.php/.phar/stub.php(2): Phar::mungServer(Array)
+#0 %sfrontcontroller19.phar.php(2): Phar::mungServer(Array)
 #1 {main}
-  thrown in %sfrontcontroller19.phar.php/.phar/stub.php on line 2
+  thrown in %sfrontcontroller19.phar.php on line 2
index 7d0da748bd527c7a2f3217977c151a53885c8374..362d20ffcf34f1dd8882cc6413223bebf240796e 100644 (file)
@@ -8,8 +8,8 @@ REQUEST_URI=/frontcontroller20.phar.php/
 --FILE_EXTERNAL--
 frontcontroller11.phar.tar
 --EXPECTF--
-Fatal error: Uncaught exception 'UnexpectedValueException' with message 'Non-string value passed to Phar::mungServer(), expecting an array of any of these strings: PHP_SELF, REQUEST_URI, SCRIPT_FILENAME, SCRIPT_NAME' in %sfrontcontroller20.phar.php/.phar/stub.php:2
+Fatal error: Uncaught exception 'UnexpectedValueException' with message 'Non-string value passed to Phar::mungServer(), expecting an array of any of these strings: PHP_SELF, REQUEST_URI, SCRIPT_FILENAME, SCRIPT_NAME' in %sfrontcontroller20.phar.php:2
 Stack trace:
-#0 %sfrontcontroller20.phar.php/.phar/stub.php(2): Phar::mungServer(Array)
+#0 %sfrontcontroller20.phar.php(2): Phar::mungServer(Array)
 #1 {main}
-  thrown in %sfrontcontroller20.phar.php/.phar/stub.php on line 2
+  thrown in %sfrontcontroller20.phar.php on line 2
diff --git a/ext/phar/tests/tar/phar_commitwrite.phpt b/ext/phar/tests/tar/phar_commitwrite.phpt
new file mode 100644 (file)
index 0000000..874ce5f
--- /dev/null
@@ -0,0 +1,44 @@
+--TEST--
+Phar::setStub()/stopBuffering() tar-based
+--SKIPIF--
+<?php if (!extension_loaded("phar")) die("skip"); ?>
+--INI--
+phar.require_hash=0
+phar.readonly=0
+--FILE--
+<?php
+$p = new Phar(dirname(__FILE__) . '/brandnewphar.phar.tar', 0, 'brandnewphar.phar');
+$p['file1.txt'] = 'hi';
+$p->stopBuffering();
+var_dump($p->getStub());
+$p->setStub("<?php
+function __autoload(\$class)
+{
+    include 'phar://' . str_replace('_', '/', \$class);
+}
+Phar::mapPhar('brandnewphar.phar');
+include 'phar://brandnewphar.phar/startup.php';
+__HALT_COMPILER();
+?>");
+var_dump($p->getStub());
+var_dump($p->isTar());
+?>
+===DONE===
+--CLEAN--
+<?php 
+unlink(dirname(__FILE__) . '/brandnewphar.phar.tar');
+?>
+--EXPECT--
+string(60) "<?php // tar-based phar archive stub file
+__HALT_COMPILER();"
+string(200) "<?php
+function __autoload($class)
+{
+    include 'phar://' . str_replace('_', '/', $class);
+}
+Phar::mapPhar('brandnewphar.phar');
+include 'phar://brandnewphar.phar/startup.php';
+__HALT_COMPILER(); ?>
+"
+bool(true)
+===DONE===
\ No newline at end of file
diff --git a/ext/phar/tests/tar/phar_copy.phpt b/ext/phar/tests/tar/phar_copy.phpt
new file mode 100644 (file)
index 0000000..2750e85
--- /dev/null
@@ -0,0 +1,56 @@
+--TEST--
+Phar: copy() tar-based
+--SKIPIF--
+<?php if (!extension_loaded("phar")) die("skip"); ?>
+<?php if (!extension_loaded("spl")) die("skip SPL not available"); ?>
+<?php if (!extension_loaded("zlib")) die("skip zlib not available"); ?>
+--INI--
+phar.readonly=0
+phar.require_hash=1
+--FILE--
+<?php
+
+$fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.tar.php';
+$fname2 = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '2.phar.php';
+
+$pname = 'phar://'.$fname;
+$iname = '/file.txt';
+$ename = '/error/';
+
+$p = new Phar($fname);
+
+try
+{
+       $p['a'] = 'hi';
+       $p->startBuffering();
+       $p->copy('a', 'b');
+       echo file_get_contents($p['b']->getPathName());
+       $p->copy('b', 'c');
+       $p->stopBuffering();
+       echo file_get_contents($p['c']->getPathName());
+       copy($fname, $fname2);
+       var_dump($p->isTar());
+       $p->copy('a', $ename);
+}
+catch(Exception $e)
+{
+       echo $e->getMessage() . "\n";
+}
+ini_set('phar.readonly',1);
+$p2 = new Phar($fname2);
+var_dump($p2->isTar());
+echo "\n";
+echo 'a: ' , file_get_contents($p2['a']->getPathName());
+echo 'b: ' ,file_get_contents($p2['b']->getPathName());
+echo 'c: ' ,file_get_contents($p2['c']->getPathName());
+?>
+===DONE===
+--CLEAN--
+<?php unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar.tar.php'); ?>
+<?php unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '2.phar.php'); ?>
+--EXPECTF--
+hihibool(true)
+file "/error/" contains invalid characters empty directory, cannot be copied from "a" in phar %s
+bool(true)
+
+a: hib: hic: hi===DONE===
\ No newline at end of file
diff --git a/ext/phar/tests/tar/phar_magic.phpt b/ext/phar/tests/tar/phar_magic.phpt
new file mode 100644 (file)
index 0000000..e2da216
--- /dev/null
@@ -0,0 +1,32 @@
+--TEST--
+Phar: include/fopen magic tar-based
+--SKIPIF--
+<?php if (!extension_loaded("phar")) die("skip"); ?>
+--INI--
+phar.require_hash=0
+phar.readonly=0
+--FILE--
+<?php
+$fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.tar.php';
+$p = new Phar($fname);
+var_dump($p->isTar());
+$p['a'] = '<?php include "b/c.php";' . "\n";
+$p['b/c.php'] = '<?php echo "in b\n";$a = fopen("a", "r", true);echo stream_get_contents($a);fclose($a);include dirname(__FILE__) . "/../d";';
+$p['d'] = "in d\n";
+$p->setStub('<?php
+include "phar://" . __FILE__ . "/a";
+__HALT_COMPILER();');
+include $fname;
+?>
+===DONE===
+--CLEAN--
+<?php 
+unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar.tar.php');
+__HALT_COMPILER();
+?>
+--EXPECTF--
+bool(true)
+in b
+<?php include "b/c.php";
+in d
+===DONE===
diff --git a/ext/phar/tests/tar/phar_setalias.phpt b/ext/phar/tests/tar/phar_setalias.phpt
new file mode 100644 (file)
index 0000000..db6a223
--- /dev/null
@@ -0,0 +1,42 @@
+--TEST--
+Phar::setAlias() tar-based
+--SKIPIF--
+<?php if (!extension_loaded("phar")) die("skip"); ?>
+--INI--
+phar.require_hash=0
+phar.readonly=0
+--FILE--
+<?php
+include dirname(__FILE__) . '/tarmaker.php.inc';
+$fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php';
+$pname = 'phar://' . $fname;
+$a = new tarmaker($fname, 'none');
+$a->init();
+$a->addFile('.phar/stub.php', '<?php echo "first stub\n"; __HALT_COMPILER(); ?>');
+
+$files = array();
+$files['a'] = 'a';
+$files['b'] = 'b';
+$files['c'] = 'c';
+$files['.phar/alias.txt'] = 'hio';
+foreach ($files as $n => $file) {
+$a->addFile($n, $file);
+}
+$a->close();
+
+$phar = new Phar($fname);
+echo $phar->getAlias() . "\n";
+$phar->setAlias('test');
+echo $phar->getAlias() . "\n";
+?>
+===DONE===
+--CLEAN--
+<?php 
+unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar.php');
+unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phartmp.php');
+__HALT_COMPILER();
+?>
+--EXPECT--
+hio
+test
+===DONE===
diff --git a/ext/phar/tests/tar/phar_setalias2.phpt b/ext/phar/tests/tar/phar_setalias2.phpt
new file mode 100644 (file)
index 0000000..63be3b5
--- /dev/null
@@ -0,0 +1,50 @@
+--TEST--
+Phar::setAlias() error tar-based
+--SKIPIF--
+<?php if (!extension_loaded("phar")) die("skip"); ?>
+--INI--
+phar.require_hash=0
+phar.readonly=0
+--FILE--
+<?php
+include dirname(__FILE__) . '/tarmaker.php.inc';
+$fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php';
+$pname = 'phar://' . $fname;
+$a = new tarmaker($fname, 'none');
+$a->init();
+$a->addFile('.phar/stub.php', '<?php echo "first stub\n"; __HALT_COMPILER(); ?>');
+
+$files = array();
+$files['a'] = 'a';
+$files['b'] = 'b';
+$files['c'] = 'c';
+$files['.phar/alias.txt'] = 'hio';
+foreach ($files as $n => $file) {
+$a->addFile($n, $file);
+}
+$a->close();
+
+$phar = new Phar($fname);
+echo $phar->getAlias() . "\n";
+$phar->setAlias('test');
+echo $phar->getAlias() . "\n";
+$phar = new Phar(dirname(__FILE__) . '/notphar.phar');
+try {
+       $phar->setAlias('test');
+} catch (Exception $e) {
+       echo $e->getMessage() . "\n";
+}
+?>
+===DONE===
+--CLEAN--
+<?php 
+unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar.php');
+unlink(dirname(__FILE__) . '/notphar.phar');
+unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phartmp.php');
+__HALT_COMPILER();
+?>
+--EXPECTF--
+hio
+test
+alias "test" is already used for archive "%sphar_setalias2.phar.php" and cannot be used for other archives
+===DONE===
diff --git a/ext/phar/tests/tar/phar_stub_error.phpt b/ext/phar/tests/tar/phar_stub_error.phpt
new file mode 100755 (executable)
index 0000000..c4cee76
--- /dev/null
@@ -0,0 +1,61 @@
+--TEST--
+Phar::setStub()/getStub()
+--SKIPIF--
+<?php if (!extension_loaded("phar")) die("skip"); ?>
+--INI--
+phar.require_hash=0
+phar.readonly=0
+--FILE--
+<?php
+include dirname(__FILE__) . '/tarmaker.php.inc';
+$fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php';
+$pname = 'phar://' . $fname;
+$a = new tarmaker($fname, 'none');
+$a->init();
+$a->addFile('.phar/stub.php', $stub = '<?php echo "first stub\n"; __HALT_COMPILER(); ?>');
+
+$files = array();
+$files['a'] = 'a';
+$files['.phar/alias.txt'] = 'hio';
+foreach ($files as $n => $file) {
+$a->addFile($n, $file);
+}
+$a->close();
+
+$phar = new Phar($fname);
+var_dump($stub);
+var_dump($phar->getStub());
+var_dump($phar->getStub() == $stub);
+
+$newstub = '<?php echo "second stub\n"; _x_HALT_COMPILER(); ?>';
+try
+{
+       $phar->setStub($newstub);
+}
+catch(exception $e)
+{
+       echo 'Exception: ' . $e->getMessage() . "\n";
+}
+var_dump($phar->getStub());
+var_dump($phar->getStub() == $stub);
+$phar->stopBuffering();
+var_dump($phar->getStub());
+var_dump($phar->getStub() == $stub);
+
+?>
+===DONE===
+--CLEAN--
+<?php 
+unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar.php');
+__HALT_COMPILER();
+?>
+--EXPECTF--
+string(48) "<?php echo "first stub\n"; __HALT_COMPILER(); ?>"
+string(48) "<?php echo "first stub\n"; __HALT_COMPILER(); ?>"
+bool(true)
+Exception: illegal stub for tar-based phar "%sphar_stub_error.phar.php"
+string(48) "<?php echo "first stub\n"; __HALT_COMPILER(); ?>"
+bool(true)
+string(48) "<?php echo "first stub\n"; __HALT_COMPILER(); ?>"
+bool(true)
+===DONE===
diff --git a/ext/phar/tests/tar/refcount1.phpt b/ext/phar/tests/tar/refcount1.phpt
new file mode 100644 (file)
index 0000000..add9ebf
--- /dev/null
@@ -0,0 +1,70 @@
+--TEST--
+Phar: test that refcounting avoids problems with deleting a file tar-based
+--SKIPIF--
+<?php if (!extension_loaded("phar")) die("skip"); ?>
+<?php if (!extension_loaded("spl")) die("skip SPL not available"); ?>
+<?php if (version_compare(PHP_VERSION, "5.3", "<")) die("skip requires 5.3 or later"); ?>
+--INI--
+phar.readonly=0
+phar.require_hash=0
+--FILE--
+<?php
+include dirname(__FILE__) . '/tarmaker.php.inc';
+$fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php';
+$pname = 'phar://' . $fname;
+$a = new tarmaker($fname, 'none');
+$a->init();
+$a->addFile('.phar/stub.php', "<?php __HALT_COMPILER(); ?>");
+
+
+$files = array();
+$files['a.php'] = '<?php echo "This is a\n"; ?>';
+$files['b.php'] = '<?php echo "This is b\n"; ?>';
+$files['b/c.php'] = '<?php echo "This is b/c\n"; ?>';
+$files['.phar/alias.txt'] = 'hio';
+foreach ($files as $n => $file) {
+$a->addFile($n, $file);
+}
+$a->close();
+
+$fp = fopen($pname . '/b/c.php', 'wb');
+fwrite($fp, "extra");
+fclose($fp);
+echo "===CLOSE===\n";
+$p = new Phar($fname);
+$b = fopen($pname . '/b/c.php', 'rb');
+$a = $p['b/c.php'];
+var_dump($a);
+var_dump(fread($b, 20));
+rewind($b);
+echo "===UNLINK===\n";
+unlink($pname . '/b/c.php');
+var_dump($a);
+var_dump(fread($b, 20));
+include $pname . '/b/c.php';
+?>
+
+===DONE===
+--CLEAN--
+<?php unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar.php'); ?>
+--EXPECTF--
+===CLOSE===
+object(PharFileInfo)#%d (2) {
+  ["pathName":"SplFileInfo":private]=>
+  string(%d) "phar://%srefcount1.phar.php/b"
+  ["fileName":"SplFileInfo":private]=>
+  string(%d) "phar://%srefcount1.phar.php/b/c.php"
+}
+string(5) "extra"
+===UNLINK===
+
+Warning: unlink(): phar error: "b/c.php" in phar "%srefcount1.phar.php", has open file pointers, cannot unlink in %srefcount1.php on line %d
+object(PharFileInfo)#%d (2) {
+  ["pathName":"SplFileInfo":private]=>
+  string(%d) "phar://%srefcount1.phar.php/b"
+  ["fileName":"SplFileInfo":private]=>
+  string(%s) "phar://%srefcount1.phar.php/b/c.php"
+}
+string(5) "extra"
+extra
+===DONE===
diff --git a/ext/phar/tests/tar/refcount1_5_2.phpt b/ext/phar/tests/tar/refcount1_5_2.phpt
new file mode 100755 (executable)
index 0000000..f0e52ca
--- /dev/null
@@ -0,0 +1,62 @@
+--TEST--
+Phar: test that refcounting avoids problems with deleting a file tar-based
+--SKIPIF--
+<?php if (!extension_loaded("phar")) die("skip"); ?>
+<?php if (!extension_loaded("spl")) die("skip SPL not available"); ?>
+<?php if (version_compare(PHP_VERSION, "5.2", ">")) die("skip requires 5.2 or earlier"); ?>
+--INI--
+phar.readonly=0
+phar.require_hash=0
+--FILE--
+<?php
+include dirname(__FILE__) . '/tarmaker.php.inc';
+$fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php';
+$pname = 'phar://' . $fname;
+$a = new tarmaker($fname, 'none');
+$a->init();
+$a->addFile('.phar/stub.php', "<?php __HALT_COMPILER(); ?>");
+
+
+$files = array();
+$files['a.php'] = '<?php echo "This is a\n"; ?>';
+$files['b.php'] = '<?php echo "This is b\n"; ?>';
+$files['b/c.php'] = '<?php echo "This is b/c\n"; ?>';
+$files['.phar/alias.txt'] = 'hio';
+foreach ($files as $n => $file) {
+$a->addFile($n, $file);
+}
+$a->close();
+
+$fp = fopen($pname . '/b/c.php', 'wb');
+fwrite($fp, "extra");
+fclose($fp);
+echo "===CLOSE===\n";
+$p = new Phar($fname);
+$b = fopen($pname . '/b/c.php', 'rb');
+$a = $p['b/c.php'];
+var_dump($a);
+var_dump(fread($b, 20));
+rewind($b);
+echo "===UNLINK===\n";
+unlink($pname . '/b/c.php');
+var_dump($a);
+var_dump(fread($b, 20));
+include $pname . '/b/c.php';
+?>
+
+===DONE===
+--CLEAN--
+<?php unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar.php'); ?>
+--EXPECTF--
+===CLOSE===
+object(PharFileInfo)#%d (0) {
+}
+string(5) "extra"
+===UNLINK===
+
+Warning: unlink(): phar error: "b/c.php" in phar "%sefcount1.phar.php", has open file pointers, cannot unlink in %sefcount1.php on line %d
+object(PharFileInfo)#%d (0) {
+}
+string(5) "extra"
+extra
+===DONE===
diff --git a/ext/phar/tests/tar/rename.phpt b/ext/phar/tests/tar/rename.phpt
new file mode 100644 (file)
index 0000000..ed410a8
--- /dev/null
@@ -0,0 +1,39 @@
+--TEST--
+Phar: rename test
+--SKIPIF--
+<?php if (!extension_loaded("phar")) die("skip"); ?>
+--INI--
+phar.readonly=0
+phar.require_hash=0
+--FILE--
+<?php
+include dirname(__FILE__) . '/tarmaker.php.inc';
+$fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php';
+$pname = 'phar://' . $fname;
+$a = new tarmaker($fname, 'none');
+$a->init();
+$a->addFile('.phar/stub.php', "<?php
+Phar::mapPhar('hio');
+__HALT_COMPILER(); ?>");
+
+$files = array();
+$files['a'] = 'a';
+foreach ($files as $n => $file) {
+$a->addFile($n, $file);
+}
+$a->close();
+
+include $fname;
+
+echo file_get_contents($pname . '/a') . "\n";
+rename($pname . '/a', $pname . '/b');
+echo file_get_contents($pname . '/b') . "\n";
+echo file_get_contents($pname . '/a') . "\n";
+?>
+--CLEAN--
+<?php unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar.php'); ?>
+--EXPECTF--
+a
+a
+
+Warning: file_get_contents(phar://%srename.phar.php/a): failed to open stream: phar error: "a" is not a file in phar "%srename.phar.php" in %srename.php on line %d
\ No newline at end of file
index 611e80bf76240e097a756ad9ba14d8c121061572..63a3dd8b91c34b123aba561545362de694eb35c6 100644 (file)
@@ -20,7 +20,7 @@ $a->mkDir('dir');
 $a->addFile('.phar/stub.php', '<?php
 Phar::mapPhar();
 var_dump("it worked");
-include "tar_004.php";
+include "phar://" . __FILE__ . "/tar_004.php";
 ');
 $a->close();