From: Greg Beaver Date: Mon, 7 Jan 2008 22:21:10 +0000 (+0000) Subject: eliminate potential double-free of alias X-Git-Tag: RELEASE_2_0_0a1~993 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=36efc2a9071395f36e69c7c8e9ef89614f6bf988;p=php eliminate potential double-free of alias 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__ --- diff --git a/ext/phar/phar.c b/ext/phar/phar.c index 046a5be406..0a0568f312 100644 --- a/ext/phar/phar.c +++ b/ext/phar/phar.c @@ -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; diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index 4f7d9c8dc2..7e9229130c 100755 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -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); diff --git a/ext/phar/tar.c b/ext/phar/tar.c index 9bd8d4f5f7..3a5b6cbf97 100644 --- a/ext/phar/tar.c +++ b/ext/phar/tar.c @@ -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; diff --git a/ext/phar/tests/tar/frontcontroller10.phar.phpt b/ext/phar/tests/tar/frontcontroller10.phar.phpt index 720fe00766..f6b52b0496 100644 --- a/ext/phar/tests/tar/frontcontroller10.phar.phpt +++ b/ext/phar/tests/tar/frontcontroller10.phar.phpt @@ -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 diff --git a/ext/phar/tests/tar/frontcontroller11.phar.phpt b/ext/phar/tests/tar/frontcontroller11.phar.phpt index a050b1f7f9..be66fd18d2 100644 --- a/ext/phar/tests/tar/frontcontroller11.phar.phpt +++ b/ext/phar/tests/tar/frontcontroller11.phar.phpt @@ -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 diff --git a/ext/phar/tests/tar/frontcontroller12.phar.phpt b/ext/phar/tests/tar/frontcontroller12.phar.phpt index 192e613e24..7427130191 100644 --- a/ext/phar/tests/tar/frontcontroller12.phar.phpt +++ b/ext/phar/tests/tar/frontcontroller12.phar.phpt @@ -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 diff --git a/ext/phar/tests/tar/frontcontroller13.phar.phpt b/ext/phar/tests/tar/frontcontroller13.phar.phpt index ad3b9fc279..6b2b4f3551 100644 --- a/ext/phar/tests/tar/frontcontroller13.phar.phpt +++ b/ext/phar/tests/tar/frontcontroller13.phar.phpt @@ -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 diff --git a/ext/phar/tests/tar/frontcontroller18.phar.phpt b/ext/phar/tests/tar/frontcontroller18.phar.phpt index 1df42d5471..3d6f8c85aa 100644 --- a/ext/phar/tests/tar/frontcontroller18.phar.phpt +++ b/ext/phar/tests/tar/frontcontroller18.phar.phpt @@ -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 diff --git a/ext/phar/tests/tar/frontcontroller19.phar.phpt b/ext/phar/tests/tar/frontcontroller19.phar.phpt index a704a5e38b..df5094b9d9 100644 --- a/ext/phar/tests/tar/frontcontroller19.phar.phpt +++ b/ext/phar/tests/tar/frontcontroller19.phar.phpt @@ -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 diff --git a/ext/phar/tests/tar/frontcontroller20.phar.phpt b/ext/phar/tests/tar/frontcontroller20.phar.phpt index 7d0da748bd..362d20ffcf 100644 --- a/ext/phar/tests/tar/frontcontroller20.phar.phpt +++ b/ext/phar/tests/tar/frontcontroller20.phar.phpt @@ -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 index 0000000000..874ce5f573 --- /dev/null +++ b/ext/phar/tests/tar/phar_commitwrite.phpt @@ -0,0 +1,44 @@ +--TEST-- +Phar::setStub()/stopBuffering() tar-based +--SKIPIF-- + +--INI-- +phar.require_hash=0 +phar.readonly=0 +--FILE-- +stopBuffering(); +var_dump($p->getStub()); +$p->setStub(""); +var_dump($p->getStub()); +var_dump($p->isTar()); +?> +===DONE=== +--CLEAN-- + +--EXPECT-- +string(60) " +" +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 index 0000000000..2750e85344 --- /dev/null +++ b/ext/phar/tests/tar/phar_copy.phpt @@ -0,0 +1,56 @@ +--TEST-- +Phar: copy() tar-based +--SKIPIF-- + + + +--INI-- +phar.readonly=0 +phar.require_hash=1 +--FILE-- +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-- + + +--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 index 0000000000..e2da21634f --- /dev/null +++ b/ext/phar/tests/tar/phar_magic.phpt @@ -0,0 +1,32 @@ +--TEST-- +Phar: include/fopen magic tar-based +--SKIPIF-- + +--INI-- +phar.require_hash=0 +phar.readonly=0 +--FILE-- +isTar()); +$p['a'] = 'setStub(' +===DONE=== +--CLEAN-- + +--EXPECTF-- +bool(true) +in b + +--INI-- +phar.require_hash=0 +phar.readonly=0 +--FILE-- +init(); +$a->addFile('.phar/stub.php', ''); + +$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-- + +--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 index 0000000000..63be3b5d07 --- /dev/null +++ b/ext/phar/tests/tar/phar_setalias2.phpt @@ -0,0 +1,50 @@ +--TEST-- +Phar::setAlias() error tar-based +--SKIPIF-- + +--INI-- +phar.require_hash=0 +phar.readonly=0 +--FILE-- +init(); +$a->addFile('.phar/stub.php', ''); + +$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-- + +--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 index 0000000000..c4cee768e8 --- /dev/null +++ b/ext/phar/tests/tar/phar_stub_error.phpt @@ -0,0 +1,61 @@ +--TEST-- +Phar::setStub()/getStub() +--SKIPIF-- + +--INI-- +phar.require_hash=0 +phar.readonly=0 +--FILE-- +init(); +$a->addFile('.phar/stub.php', $stub = ''); + +$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 = ''; +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-- + +--EXPECTF-- +string(48) "" +string(48) "" +bool(true) +Exception: illegal stub for tar-based phar "%sphar_stub_error.phar.php" +string(48) "" +bool(true) +string(48) "" +bool(true) +===DONE=== diff --git a/ext/phar/tests/tar/refcount1.phpt b/ext/phar/tests/tar/refcount1.phpt new file mode 100644 index 0000000000..add9ebfdab --- /dev/null +++ b/ext/phar/tests/tar/refcount1.phpt @@ -0,0 +1,70 @@ +--TEST-- +Phar: test that refcounting avoids problems with deleting a file tar-based +--SKIPIF-- + + + +--INI-- +phar.readonly=0 +phar.require_hash=0 +--FILE-- +init(); +$a->addFile('.phar/stub.php', ""); + + +$files = array(); +$files['a.php'] = ''; +$files['b.php'] = ''; +$files['b/c.php'] = ''; +$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-- + +--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 index 0000000000..f0e52ca2d9 --- /dev/null +++ b/ext/phar/tests/tar/refcount1_5_2.phpt @@ -0,0 +1,62 @@ +--TEST-- +Phar: test that refcounting avoids problems with deleting a file tar-based +--SKIPIF-- + + +")) die("skip requires 5.2 or earlier"); ?> +--INI-- +phar.readonly=0 +phar.require_hash=0 +--FILE-- +init(); +$a->addFile('.phar/stub.php', ""); + + +$files = array(); +$files['a.php'] = ''; +$files['b.php'] = ''; +$files['b/c.php'] = ''; +$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-- + +--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 index 0000000000..ed410a863a --- /dev/null +++ b/ext/phar/tests/tar/rename.phpt @@ -0,0 +1,39 @@ +--TEST-- +Phar: rename test +--SKIPIF-- + +--INI-- +phar.readonly=0 +phar.require_hash=0 +--FILE-- +init(); +$a->addFile('.phar/stub.php', ""); + +$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-- + +--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 diff --git a/ext/phar/tests/tar/tar_004.phpt b/ext/phar/tests/tar/tar_004.phpt index 611e80bf76..63a3dd8b91 100644 --- a/ext/phar/tests/tar/tar_004.phpt +++ b/ext/phar/tests/tar/tar_004.phpt @@ -20,7 +20,7 @@ $a->mkDir('dir'); $a->addFile('.phar/stub.php', 'close();