diff --git a/ext/phar/dirstream.c b/ext/phar/dirstream.c index 64cace889922..4b35c95b6ff0 100644 --- a/ext/phar/dirstream.c +++ b/ext/phar/dirstream.c @@ -276,7 +276,7 @@ php_stream *phar_wrapper_open_dir(php_stream_wrapper *wrapper, const char *path, phar_request_initialize(); - if (FAILURE == phar_get_archive(&phar, ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), NULL, 0, &error)) { + if (FAILURE == phar_get_archive(&phar, ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), NULL, &error)) { if (error) { php_stream_wrapper_log_error(wrapper, options, "%s", error); efree(error); @@ -355,7 +355,7 @@ int phar_wrapper_mkdir(php_stream_wrapper *wrapper, const char *url_from, int mo return 0; } - if (FAILURE == phar_get_archive(&phar, ZSTR_VAL(arch), ZSTR_LEN(arch), NULL, 0, NULL)) { + if (FAILURE == phar_get_archive(&phar, ZSTR_VAL(arch), ZSTR_LEN(arch), NULL, NULL)) { phar = NULL; } @@ -383,7 +383,7 @@ int phar_wrapper_mkdir(php_stream_wrapper *wrapper, const char *url_from, int mo return 0; } - if (FAILURE == phar_get_archive(&phar, ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), NULL, 0, &error)) { + if (FAILURE == phar_get_archive(&phar, ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), NULL, &error)) { php_stream_wrapper_log_error(wrapper, options, "phar error: cannot create directory \"%s\" in phar \"%s\", error retrieving phar information: %s", ZSTR_VAL(resource->path) + 1, ZSTR_VAL(resource->host), error); efree(error); php_url_free(resource); @@ -481,7 +481,7 @@ int phar_wrapper_rmdir(php_stream_wrapper *wrapper, const char *url, int options return 0; } - if (FAILURE == phar_get_archive(&phar, ZSTR_VAL(arch), ZSTR_LEN(arch), NULL, 0, NULL)) { + if (FAILURE == phar_get_archive(&phar, ZSTR_VAL(arch), ZSTR_LEN(arch), NULL, NULL)) { phar = NULL; } @@ -509,7 +509,7 @@ int phar_wrapper_rmdir(php_stream_wrapper *wrapper, const char *url, int options return 0; } - if (FAILURE == phar_get_archive(&phar, ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), NULL, 0, &error)) { + if (FAILURE == phar_get_archive(&phar, ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), NULL, &error)) { php_stream_wrapper_log_error(wrapper, options, "phar error: cannot remove directory \"%s\" in phar \"%s\", error retrieving phar information: %s", ZSTR_VAL(resource->path)+1, ZSTR_VAL(resource->host), error); efree(error); php_url_free(resource); diff --git a/ext/phar/func_interceptors.c b/ext/phar/func_interceptors.c index 20ce0e8d7258..5adffc850eb5 100644 --- a/ext/phar/func_interceptors.c +++ b/ext/phar/func_interceptors.c @@ -99,7 +99,7 @@ static zend_string* phar_get_name_for_relative_paths(zend_string *filename, bool /* fopen within phar, if :// is not in the url, then prepend phar:/// */ /* retrieving a file defaults to within the current directory, so use this if possible */ phar_archive_data *phar; - if (FAILURE == phar_get_archive(&phar, ZSTR_VAL(arch), ZSTR_LEN(arch), NULL, 0, NULL)) { + if (FAILURE == phar_get_archive(&phar, ZSTR_VAL(arch), ZSTR_LEN(arch), NULL, NULL)) { zend_string_release_ex(arch, false); return NULL; } @@ -494,7 +494,7 @@ static void phar_file_stat(const char *filename, size_t filename_length, int typ zend_string *arch = phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), NULL, 2, 0); if (arch) { /* fopen within phar, if :// is not in the url, then prepend phar:/// */ - zend_result has_archive = phar_get_archive(&phar, ZSTR_VAL(arch), ZSTR_LEN(arch), NULL, 0, NULL); + zend_result has_archive = phar_get_archive(&phar, ZSTR_VAL(arch), ZSTR_LEN(arch), NULL, NULL); zend_string_release_ex(arch, false); if (FAILURE == has_archive) { goto skip_phar; @@ -733,7 +733,7 @@ PHP_FUNCTION(phar_is_file) /* {{{ */ /* fopen within phar, if :// is not in the url, then prepend phar:/// */ /* retrieving a file within the current directory, so use this if possible */ - zend_result has_archive = phar_get_archive(&phar, ZSTR_VAL(arch), ZSTR_LEN(arch), NULL, 0, NULL); + zend_result has_archive = phar_get_archive(&phar, ZSTR_VAL(arch), ZSTR_LEN(arch), NULL, NULL); zend_string_release_ex(arch, false); if (has_archive == SUCCESS) { phar_entry_info *etemp; @@ -790,7 +790,7 @@ PHP_FUNCTION(phar_is_link) /* {{{ */ /* fopen within phar, if :// is not in the url, then prepend phar:/// */ /* retrieving a file within the current directory, so use this if possible */ - zend_result has_archive = phar_get_archive(&phar, ZSTR_VAL(arch), ZSTR_LEN(arch), NULL, 0, NULL); + zend_result has_archive = phar_get_archive(&phar, ZSTR_VAL(arch), ZSTR_LEN(arch), NULL, NULL); zend_string_release_ex(arch, false); if (has_archive == SUCCESS) { phar_entry_info *etemp; diff --git a/ext/phar/phar.c b/ext/phar/phar.c index 3008316f6274..a49e8cff5ae9 100644 --- a/ext/phar/phar.c +++ b/ext/phar/phar.c @@ -131,7 +131,7 @@ static void phar_split_cache_list(void) /* {{{ */ len = strlen(key); } - if (SUCCESS == phar_open_from_filename(key, len, NULL, 0, 0, &phar, NULL)) { + if (SUCCESS == phar_open_from_filename(key, len, NULL, 0, &phar, NULL)) { phar->phar_pos = i++; php_stream_close(phar->fp); phar->fp = NULL; @@ -192,8 +192,8 @@ PHP_INI_END() */ void phar_destroy_phar_data(phar_archive_data *phar) /* {{{ */ { - if (phar->alias && phar->alias != phar->fname) { - pefree(phar->alias, phar->is_persistent); + if (phar->alias) { + zend_string_release_ex(phar->alias, phar->is_persistent); phar->alias = NULL; } @@ -460,6 +460,9 @@ ZEND_ATTRIBUTE_NONNULL void phar_entry_remove(phar_entry_data *idata, char **err if (signature) {\ pefree(signature, PHAR_G(persist));\ }\ + if (alias) { \ + zend_string_release_ex(alias, 0); \ + }\ MAPPHAR_ALLOC_FAIL(msg) #ifdef WORDS_BIGENDIAN @@ -484,7 +487,7 @@ ZEND_ATTRIBUTE_NONNULL void phar_entry_remove(phar_entry_data *idata, char **err /** * Open an already loaded phar */ -static zend_result phar_open_parsed_phar(char *fname, size_t fname_len, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ +static zend_result phar_open_parsed_phar(char *fname, size_t fname_len, zend_string *alias, bool is_data, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ { phar_archive_data *phar; #ifdef PHP_WIN32 @@ -504,7 +507,7 @@ static zend_result phar_open_parsed_phar(char *fname, size_t fname_len, char *al phar_unixify_path_separators(fname, fname_len); } #endif - if (SUCCESS == phar_get_archive(&phar, fname, fname_len, alias, alias_len, error) + if (SUCCESS == phar_get_archive(&phar, fname, fname_len, alias, error) && ((alias && fname_len == phar->fname_len && !strncmp(fname, phar->fname, fname_len)) || !alias) ) { @@ -723,7 +726,7 @@ void phar_parse_metadata_lazy(const char *buffer, phar_metadata_tracker *tracker * This is used by phar_open_from_filename to process the manifest, but can be called * directly. */ -static zend_result phar_parse_pharfile(php_stream *fp, char *fname, size_t fname_len, char *alias, size_t alias_len, zend_long halt_offset, phar_archive_data** pphar, uint32_t compression, char **error) /* {{{ */ +static zend_result phar_parse_pharfile(php_stream *fp, char *fname, size_t fname_len, zend_string *alias, zend_long halt_offset, phar_archive_data** pphar, uint32_t compression, char **error) /* {{{ */ { char b32[4], *buffer, *endbuffer, *savebuf; phar_archive_data *mydata = NULL; @@ -1047,7 +1050,7 @@ static zend_result phar_parse_pharfile(php_stream *fp, char *fname, size_t fname /* tmp_len = 0 says alias length is 0, which means the alias is not stored in the phar */ if (tmp_len) { /* if the alias is stored we enforce it (implicit overrides explicit) */ - if (alias && alias_len && (alias_len != tmp_len || strncmp(alias, buffer, tmp_len))) + if (alias && (ZSTR_LEN(alias) != tmp_len || strncmp(ZSTR_VAL(alias), buffer, tmp_len))) { php_stream_close(fp); @@ -1056,23 +1059,21 @@ static zend_result phar_parse_pharfile(php_stream *fp, char *fname, size_t fname } if (error) { - spprintf(error, 0, "cannot load phar \"%s\" with implicit alias \"%.*s\" under different alias \"%s\"", fname, tmp_len, buffer, alias); + spprintf(error, 0, "cannot load phar \"%s\" with implicit alias \"%.*s\" under different alias \"%s\"", fname, tmp_len, buffer, ZSTR_VAL(alias)); } efree(savebuf); return FAILURE; } - alias_len = tmp_len; - alias = buffer; + alias = zend_string_init(buffer, tmp_len, 0); buffer += tmp_len; register_alias = true; - } else if (!alias_len || !alias) { + } else if (!alias) { /* if we neither have an explicit nor an implicit alias, we use the filename */ alias = NULL; - alias_len = 0; register_alias = false; - } else if (alias_len) { + } else if (ZSTR_LEN(alias)) { register_alias = true; temp_alias = true; } @@ -1242,10 +1243,14 @@ static zend_result phar_parse_pharfile(php_stream *fp, char *fname, size_t fname } } - mydata->alias = alias ? - pestrndup(alias, alias_len, mydata->is_persistent) : - pestrndup(mydata->fname, fname_len, mydata->is_persistent); - mydata->alias_len = alias ? alias_len : fname_len; + if (alias) { + mydata->alias = zend_string_init(ZSTR_VAL(alias), ZSTR_LEN(alias), mydata->is_persistent); + } else { + mydata->alias = zend_string_init(mydata->fname, fname_len, mydata->is_persistent); + } + if (mydata->is_persistent) { + GC_MAKE_PERSISTENT_LOCAL(mydata->alias); + } mydata->sig_flags = sig_flags; mydata->fp = fp; mydata->sig_len = sig_len; @@ -1257,13 +1262,13 @@ static zend_result phar_parse_pharfile(php_stream *fp, char *fname, size_t fname mydata->is_temporary_alias = temp_alias; - if (!phar_validate_alias(mydata->alias, mydata->alias_len)) { + if (!phar_validate_alias(ZSTR_VAL(mydata->alias), ZSTR_LEN(mydata->alias))) { signature = NULL; fp = NULL; MAPPHAR_FAIL("Cannot open archive \"%s\", invalid alias"); } - if (NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len))) { + if (NULL != (fd_ptr = zend_hash_find_ptr(&(PHAR_G(phar_alias_map)), alias))) { if (SUCCESS != phar_free_alias(fd_ptr)) { signature = NULL; fp = NULL; @@ -1272,9 +1277,9 @@ static zend_result phar_parse_pharfile(php_stream *fp, char *fname, size_t fname } if (mydata->is_persistent) { - str = zend_string_init_interned(alias, alias_len, 1); + str = zend_string_init_interned(ZSTR_VAL(alias), ZSTR_LEN(alias), 1); } else { - str = zend_string_init(alias, alias_len, 0); + str = zend_string_init(ZSTR_VAL(alias), ZSTR_LEN(alias), 0); } zend_hash_add_ptr(&(PHAR_G(phar_alias_map)), str, mydata); zend_string_release(str); @@ -1291,6 +1296,10 @@ static zend_result phar_parse_pharfile(php_stream *fp, char *fname, size_t fname zend_string_release(str); efree(savebuf); + if(alias){ + zend_string_release_ex(alias, 0); + } + if (pphar) { *pphar = mydata; } @@ -1302,7 +1311,7 @@ static zend_result phar_parse_pharfile(php_stream *fp, char *fname, size_t fname /** * Create or open a phar for writing */ -ZEND_ATTRIBUTE_NONNULL_ARGS(1, 7, 8) zend_result phar_open_or_create_filename(char *fname, size_t fname_len, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ +ZEND_ATTRIBUTE_NONNULL_ARGS(1, 6, 7) zend_result phar_open_or_create_filename(char *fname, size_t fname_len, zend_string *alias, bool is_data, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ { const char *ext_str, *z; char *my_error; @@ -1328,7 +1337,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 7, 8) zend_result phar_open_or_create_filename(ch return FAILURE; } check_file: - if (phar_open_parsed_phar(fname, fname_len, alias, alias_len, is_data, options, test, &my_error) == SUCCESS) { + if (phar_open_parsed_phar(fname, fname_len, alias, is_data, options, test, &my_error) == SUCCESS) { *pphar = *test; if ((*test)->is_data && !(*test)->is_tar && !(*test)->is_zip) { @@ -1354,21 +1363,21 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 7, 8) zend_result phar_open_or_create_filename(ch if (ext_len > 3 && (z = memchr(ext_str, 'z', ext_len)) && ((ext_str + ext_len) - z >= 2) && !memcmp(z + 1, "ip", 2)) { /* assume zip-based phar */ - return phar_open_or_create_zip(fname, fname_len, alias, alias_len, is_data, options, pphar, error); + return phar_open_or_create_zip(fname, fname_len, alias, is_data, options, pphar, error); } if (ext_len > 3 && (z = memchr(ext_str, 't', ext_len)) && ((ext_str + ext_len) - z >= 2) && !memcmp(z + 1, "ar", 2)) { /* assume tar-based phar */ - return phar_open_or_create_tar(fname, fname_len, alias, alias_len, is_data, options, pphar, error); + return phar_open_or_create_tar(fname, fname_len, alias, is_data, options, pphar, error); } - return phar_create_or_parse_filename(fname, fname_len, alias, alias_len, is_data, options, pphar, error); + return phar_create_or_parse_filename(fname, fname_len, alias, is_data, options, pphar, error); } /* }}} */ -static zend_result phar_open_from_fp(php_stream* fp, char *fname, size_t fname_len, char *alias, size_t alias_len, uint32_t options, phar_archive_data** pphar, char **error); +static zend_result phar_open_from_fp(php_stream* fp, char *fname, size_t fname_len, zend_string *alias, uint32_t options, phar_archive_data** pphar, char **error); -ZEND_ATTRIBUTE_NONNULL_ARGS(1, 7, 8) zend_result phar_create_or_parse_filename(char *fname, size_t fname_len, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ +ZEND_ATTRIBUTE_NONNULL_ARGS(1, 6, 7) zend_result phar_create_or_parse_filename(char *fname, size_t fname_len, zend_string *alias, bool is_data, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ { php_stream *fp; zend_string *actual = NULL; @@ -1387,7 +1396,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 7, 8) zend_result phar_create_or_parse_filename(c } if (fp) { - if (phar_open_from_fp(fp, fname, fname_len, alias, alias_len, options, pphar, error) == SUCCESS) { + if (phar_open_from_fp(fp, fname, fname_len, alias, options, pphar, error) == SUCCESS) { if ((*pphar)->is_data || !PHAR_G(readonly)) { (*pphar)->is_writeable = 1; } @@ -1455,16 +1464,15 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 7, 8) zend_result phar_create_or_parse_filename(c if (is_data) { alias = NULL; - alias_len = 0; mydata->is_data = 1; /* assume tar format, PharData can specify other */ mydata->is_tar = 1; } else { phar_archive_data *fd_ptr; - if (alias && NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len))) { + if (alias && NULL != (fd_ptr = zend_hash_find_ptr(&(PHAR_G(phar_alias_map)), alias))) { if (SUCCESS != phar_free_alias(fd_ptr)) { - spprintf(error, 4096, "phar error: phar \"%s\" cannot set alias \"%s\", already in use by another phar archive", mydata->fname, alias); + spprintf(error, 4096, "phar error: phar \"%s\" cannot set alias \"%s\", already in use by another phar archive", mydata->fname, ZSTR_VAL(alias)); zend_hash_str_del(&(PHAR_G(phar_fname_map)), mydata->fname, fname_len); @@ -1475,14 +1483,13 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 7, 8) zend_result phar_create_or_parse_filename(c } ZEND_ASSERT(!mydata->is_persistent); - mydata->alias = alias ? estrndup(alias, alias_len) : estrndup(mydata->fname, fname_len); - mydata->alias_len = alias ? alias_len : fname_len; + mydata->alias = alias ? alias : zend_string_init(mydata->fname, fname_len, false); } - if (alias_len && alias) { - if (NULL == zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len, mydata)) { + if (alias) { + if (NULL == zend_hash_add_ptr(&(PHAR_G(phar_alias_map)), alias, mydata)) { if (options & REPORT_ERRORS) { - spprintf(error, 0, "archive \"%s\" cannot be associated with alias \"%s\", already in use", fname, alias); + spprintf(error, 0, "archive \"%s\" cannot be associated with alias \"%s\", already in use", fname, ZSTR_VAL(alias)); } zend_hash_str_del(&(PHAR_G(phar_fname_map)), mydata->fname, fname_len); @@ -1505,7 +1512,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 7, 8) zend_result phar_create_or_parse_filename(c * that the manifest is proper, then pass it to phar_parse_pharfile(). SUCCESS * or FAILURE is returned and pphar is set to a pointer to the phar's manifest */ -zend_result phar_open_from_filename(char *fname, size_t fname_len, char *alias, size_t alias_len, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ +zend_result phar_open_from_filename(char *fname, size_t fname_len, zend_string *alias, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ { php_stream *fp; zend_string *actual; @@ -1519,7 +1526,7 @@ zend_result phar_open_from_filename(char *fname, size_t fname_len, char *alias, is_data = true; } - if (phar_open_parsed_phar(fname, fname_len, alias, alias_len, is_data, options, pphar, error) == SUCCESS) { + if (phar_open_parsed_phar(fname, fname_len, alias, is_data, options, pphar, error) == SUCCESS) { return SUCCESS; } else if (error && *error) { return FAILURE; @@ -1547,7 +1554,7 @@ zend_result phar_open_from_filename(char *fname, size_t fname_len, char *alias, fname_len = ZSTR_LEN(actual); } - zend_result ret = phar_open_from_fp(fp, fname, fname_len, alias, alias_len, options, pphar, error); + zend_result ret = phar_open_from_fp(fp, fname, fname_len, alias, options, pphar, error); if (actual) { zend_string_release_ex(actual, 0); @@ -1562,7 +1569,7 @@ zend_result phar_open_from_filename(char *fname, size_t fname_len, char *alias, * that the manifest is proper, then pass it to phar_parse_pharfile(). SUCCESS * or FAILURE is returned and pphar is set to a pointer to the phar's manifest */ -static zend_result phar_open_from_fp(php_stream* fp, char *fname, size_t fname_len, char *alias, size_t alias_len, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ +static zend_result phar_open_from_fp(php_stream* fp, char *fname, size_t fname_len, zend_string *alias, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ { static const char token[] = "__HALT_COMPILER();"; static const char zip_magic[] = "PK\x03\x04"; @@ -1714,20 +1721,20 @@ static zend_result phar_open_from_fp(php_stream* fp, char *fname, size_t fname_l if (!memcmp(pos, zip_magic, 4)) { php_stream_seek(fp, 0, SEEK_END); - return phar_parse_zipfile(fp, fname, fname_len, alias, alias_len, pphar, error); + return phar_parse_zipfile(fp, fname, fname_len, alias, pphar, error); } if (got >= 512) { if (phar_is_tar(pos, fname)) { php_stream_rewind(fp); - return phar_parse_tarfile(fp, fname, fname_len, alias, alias_len, pphar, compression, error); + return phar_parse_tarfile(fp, fname, fname_len, alias, pphar, compression, error); } } } if (got > 0 && (pos = php_memnistr(buffer, token, tokenlen, buffer + got + sizeof(token))) != NULL) { halt_offset += (pos - buffer); /* no -tokenlen+tokenlen here */ - return phar_parse_pharfile(fp, fname, fname_len, alias, alias_len, halt_offset, pphar, compression, error); + return phar_parse_pharfile(fp, fname, fname_len, alias, halt_offset, pphar, compression, error); } halt_offset += got; @@ -2247,7 +2254,7 @@ zend_string* phar_split_fname(const char *filename, size_t filename_len, zend_st * Invoked when a user calls Phar::mapPhar() from within an executing .phar * to set up its manifest directly */ -ZEND_ATTRIBUTE_NONNULL_ARGS(3) zend_result phar_open_executed_filename(char *alias, size_t alias_len, char **error) /* {{{ */ +ZEND_ATTRIBUTE_NONNULL_ARGS(2) zend_result phar_open_executed_filename(zend_string *alias, char **error) /* {{{ */ { *error = NULL; @@ -2258,7 +2265,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(3) zend_result phar_open_executed_filename(char *ali return FAILURE; } - if (phar_open_parsed_phar(ZSTR_VAL(fname), ZSTR_LEN(fname), alias, alias_len, false, REPORT_ERRORS, NULL, NULL) == SUCCESS) { + if (phar_open_parsed_phar(ZSTR_VAL(fname), ZSTR_LEN(fname), alias, false, REPORT_ERRORS, NULL, NULL) == SUCCESS) { return SUCCESS; } @@ -2287,7 +2294,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(3) zend_result phar_open_executed_filename(char *ali fname = actual; } - zend_result ret = phar_open_from_fp(fp, ZSTR_VAL(fname), ZSTR_LEN(fname), alias, alias_len, REPORT_ERRORS, NULL, error); + zend_result ret = phar_open_from_fp(fp, ZSTR_VAL(fname), ZSTR_LEN(fname), alias, REPORT_ERRORS, NULL, error); if (actual) { zend_string_release_ex(actual, 0); @@ -2470,7 +2477,6 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_flush_ex(phar_archive_data *phar, zen phar_entry_info *entry, *newentry; size_t halt_offset; - uint32_t restore_alias_len; uint32_t global_flags = 0; bool must_close_old_file = false; bool has_dirs = false; @@ -2765,12 +2771,14 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_flush_ex(phar_archive_data *phar, zen * 4: phar metadata length * ?: phar metadata */ - restore_alias_len = phar->alias_len; - if (phar->is_temporary_alias) { - phar->alias_len = 0; + size_t written_alias_len; + if (phar->is_temporary_alias || !phar->alias) { + written_alias_len = 0; + } else { + written_alias_len = ZSTR_LEN(phar->alias); } - manifest_len = offset + phar->alias_len + sizeof(manifest) + (main_metadata_str.s ? ZSTR_LEN(main_metadata_str.s) : 0); + manifest_len = offset + written_alias_len + sizeof(manifest) + (main_metadata_str.s ? ZSTR_LEN(main_metadata_str.s) : 0); phar_set_32(manifest, manifest_len); /* Hack - see bug #65028, add padding byte to the end of the manifest */ if(manifest[0] == '\r' || manifest[0] == '\n') { @@ -2787,25 +2795,22 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_flush_ex(phar_archive_data *phar, zen *(manifest + 9) = (unsigned char) (((PHAR_API_VERSION_NODIR) & 0xF0)); } phar_set_32(manifest+10, global_flags); - phar_set_32(manifest+14, phar->alias_len); + phar_set_32(manifest+14, written_alias_len); /* write the manifest header */ if (sizeof(manifest) != php_stream_write(newfile, manifest, sizeof(manifest)) - || (size_t)phar->alias_len != php_stream_write(newfile, phar->alias, phar->alias_len)) { - + || (written_alias_len > 0 && written_alias_len != php_stream_write(newfile, ZSTR_VAL(phar->alias), written_alias_len))) { if (must_close_old_file) { php_stream_close(oldfile); } php_stream_close(newfile); - phar->alias_len = restore_alias_len; spprintf(error, 0, "unable to write manifest header of new phar \"%s\"", phar->fname); goto cleanup; } - phar->alias_len = restore_alias_len; phar_set_32(manifest, main_metadata_str.s ? ZSTR_LEN(main_metadata_str.s) : 0); if (4 != php_stream_write(newfile, manifest, 4) || ((main_metadata_str.s ? ZSTR_LEN(main_metadata_str.s) : 0) @@ -2817,7 +2822,6 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_flush_ex(phar_archive_data *phar, zen } php_stream_close(newfile); - phar->alias_len = restore_alias_len; spprintf(error, 0, "unable to write manifest meta-data of new phar \"%s\"", phar->fname); @@ -3156,7 +3160,7 @@ static zend_op_array *phar_compile_file(zend_file_handle *file_handle, int type) return phar_orig_compile_file(file_handle, type); } if (strstr(ZSTR_VAL(file_handle->filename), ".phar") && !strstr(ZSTR_VAL(file_handle->filename), "://")) { - if (SUCCESS == phar_open_from_filename(ZSTR_VAL(file_handle->filename), ZSTR_LEN(file_handle->filename), NULL, 0, 0, &phar, NULL)) { + if (SUCCESS == phar_open_from_filename(ZSTR_VAL(file_handle->filename), ZSTR_LEN(file_handle->filename), NULL, 0, &phar, NULL)) { if (phar->is_zip || phar->is_tar) { zend_file_handle f; diff --git a/ext/phar/phar_internal.h b/ext/phar/phar_internal.h index 34f221f43e0e..f0e9469761d7 100644 --- a/ext/phar/phar_internal.h +++ b/ext/phar/phar_internal.h @@ -149,7 +149,7 @@ ZEND_BEGIN_MODULE_GLOBALS(phar) char* last_phar_name; uint32_t last_phar_name_len; uint32_t last_alias_len; - const char* last_alias; + zend_string* last_alias; phar_archive_data* last_phar; HashTable mime_types; ZEND_END_MODULE_GLOBALS(phar) @@ -248,8 +248,7 @@ struct _phar_archive_data { /* for phar_detect_fname_ext, this stores the location of the file extension within fname */ uint32_t ext_len; char *ext; - char *alias; - uint32_t alias_len; + zend_string *alias; char version[12]; size_t halt_offset; HashTable manifest; @@ -409,12 +408,12 @@ void phar_object_init(void); void phar_destroy_phar_data(phar_archive_data *phar); ZEND_ATTRIBUTE_NONNULL zend_result phar_postprocess_file(phar_entry_data *idata, uint32_t crc32, char **error, int process_zip); -zend_result phar_open_from_filename(char *fname, size_t fname_len, char *alias, size_t alias_len, uint32_t options, phar_archive_data** pphar, char **error); -ZEND_ATTRIBUTE_NONNULL_ARGS(1, 7, 8) zend_result phar_open_or_create_filename(char *fname, size_t fname_len, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error); -ZEND_ATTRIBUTE_NONNULL_ARGS(1, 7, 8) zend_result phar_create_or_parse_filename(char *fname, size_t fname_len, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error); -ZEND_ATTRIBUTE_NONNULL_ARGS(3) zend_result phar_open_executed_filename(char *alias, size_t alias_len, char **error); +zend_result phar_open_from_filename(char *fname, size_t fname_len, zend_string *alias,uint32_t options, phar_archive_data** pphar, char **error); +ZEND_ATTRIBUTE_NONNULL_ARGS(1, 6, 7) zend_result phar_open_or_create_filename(char *fname, size_t fname_len, zend_string *alias, bool is_data, uint32_t options, phar_archive_data** pphar, char **error); +ZEND_ATTRIBUTE_NONNULL_ARGS(1, 6, 7) zend_result phar_create_or_parse_filename(char *fname, size_t fname_len, zend_string *alias, bool is_data, uint32_t options, phar_archive_data** pphar, char **error); +ZEND_ATTRIBUTE_NONNULL_ARGS(2) zend_result phar_open_executed_filename(zend_string *alias, char **error); zend_result phar_free_alias(const phar_archive_data *phar); -zend_result phar_get_archive(phar_archive_data **archive, const char *fname, size_t fname_len, const char *alias, size_t alias_len, char **error); +zend_result phar_get_archive(phar_archive_data **archive, const char *fname, size_t fname_len, zend_string *alias, char **error); zend_result phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t sig_type, char *sig, size_t sig_len, const char *fname, char **signature, size_t *signature_len, char **error); ZEND_ATTRIBUTE_NONNULL zend_result phar_create_signature(phar_archive_data *phar, php_stream *fp, char **signature, size_t *signature_length, char **error); @@ -448,13 +447,13 @@ zend_result phar_copy_on_write(phar_archive_data **pphar); /* tar functions in tar.c */ bool phar_is_tar(const char *buf, const char *fname); -zend_result phar_parse_tarfile(php_stream* fp, const char *fname, size_t fname_len, const char *alias, size_t alias_len, phar_archive_data** pphar, uint32_t compression, char **error); -ZEND_ATTRIBUTE_NONNULL_ARGS(1, 7, 8) zend_result phar_open_or_create_tar(char *fname, size_t fname_len, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error); +zend_result phar_parse_tarfile(php_stream* fp, const char *fname, size_t fname_len, zend_string *alias, phar_archive_data** pphar, uint32_t compression, char **error); +ZEND_ATTRIBUTE_NONNULL_ARGS(1, 6, 7) zend_result phar_open_or_create_tar(char *fname, size_t fname_len, zend_string *alias, bool is_data, uint32_t options, phar_archive_data** pphar, char **error); ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_tar_flush(phar_archive_data *phar, zend_string *user_stub, bool is_default_stub, char **error); /* zip functions in zip.c */ -zend_result phar_parse_zipfile(php_stream *fp, const char *fname, size_t fname_len, const char *alias, size_t alias_len, phar_archive_data** pphar, char **error); -ZEND_ATTRIBUTE_NONNULL_ARGS(1, 7, 8) zend_result phar_open_or_create_zip(char *fname, size_t fname_len, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error); +zend_result phar_parse_zipfile(php_stream *fp, const char *fname, size_t fname_len, zend_string *alias, phar_archive_data** pphar, char **error); +ZEND_ATTRIBUTE_NONNULL_ARGS(1, 6, 7) zend_result phar_open_or_create_zip(char *fname, size_t fname_len, zend_string *alias, bool is_data, uint32_t options, phar_archive_data** pphar, char **error); ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_zip_flush(phar_archive_data *archive, zend_string *user_stub, bool is_default_stub, char **error); #ifdef PHAR_MAIN diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index 07058eefc461..70d2e93ebb61 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -542,8 +542,8 @@ PHP_METHOD(Phar, webPhar) zval *mimeoverride = NULL; zend_fcall_info rewrite_fci = {0}; zend_fcall_info_cache rewrite_fcc; - char *alias = NULL, *error, *index_php = NULL, *ru = NULL; - size_t alias_len = 0, free_pathinfo = 0; + char *error, *index_php = NULL, *ru = NULL; + size_t free_pathinfo = 0; zend_string *f404 = NULL; size_t ru_len = 0; char *fname, *path_info, *mime_type = NULL, *entry, *pt; @@ -555,14 +555,15 @@ PHP_METHOD(Phar, webPhar) phar_entry_info *info = NULL; size_t sapi_mod_name_len = strlen(sapi_module.name); phar_action_status status = PHAR_ACT_DO_EXIT; + zend_string *alias = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "|s!s!S!af!", &alias, &alias_len, &index_php, &index_php_len, &f404, &mimeoverride, &rewrite_fci, &rewrite_fcc) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|S!s!S!af!", &alias, &index_php, &index_php_len, &f404, &mimeoverride, &rewrite_fci, &rewrite_fcc) == FAILURE) { RETURN_THROWS(); } phar_request_initialize(); - if (phar_open_executed_filename(alias, alias_len, &error) != SUCCESS) { + if (phar_open_executed_filename(alias, &error) != SUCCESS) { if (error) { zend_throw_exception_ex(phar_ce_PharException, 0, "%s", error); efree(error); @@ -740,7 +741,7 @@ PHP_METHOD(Phar, webPhar) entry_len = sizeof("/index.php")-1; } - if (FAILURE == phar_get_archive(&phar, fname, fname_len, NULL, 0, NULL) || + if (FAILURE == phar_get_archive(&phar, fname, fname_len, NULL, NULL) || (info = phar_get_entry_info(phar, entry, entry_len, NULL, false)) == NULL) { phar_do_404(phar, fname, fname_len, f404); } else { @@ -781,7 +782,7 @@ PHP_METHOD(Phar, webPhar) goto cleanup_skip_entry; } - if (FAILURE == phar_get_archive(&phar, fname, fname_len, NULL, 0, NULL) || + if (FAILURE == phar_get_archive(&phar, fname, fname_len, NULL, NULL) || (info = phar_get_entry_info(phar, entry, entry_len, NULL, false)) == NULL) { phar_do_404(phar, fname, fname_len, f404); goto cleanup; @@ -934,17 +935,17 @@ PHP_METHOD(Phar, createDefaultStub) /* {{{ Reads the currently executed file (a phar) and registers its manifest */ PHP_METHOD(Phar, mapPhar) { - char *alias = NULL, *error; - size_t alias_len = 0; + char *error; + zend_string *alias = NULL; zend_long dataoffset = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "|s!l", &alias, &alias_len, &dataoffset) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|S!l", &alias, &dataoffset) == FAILURE) { RETURN_THROWS(); } phar_request_initialize(); - RETVAL_BOOL(phar_open_executed_filename(alias, alias_len, &error) == SUCCESS); + RETVAL_BOOL(phar_open_executed_filename(alias, &error) == SUCCESS); if (error) { zend_throw_exception_ex(phar_ce_PharException, 0, "%s", error); @@ -955,16 +956,17 @@ PHP_METHOD(Phar, mapPhar) /* {{{ Loads any phar archive with an alias */ PHP_METHOD(Phar, loadPhar) { - char *fname, *alias = NULL, *error; - size_t fname_len, alias_len = 0; + char *fname, *error; + size_t fname_len = 0; + zend_string *alias = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "p|s!", &fname, &fname_len, &alias, &alias_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "p|S", &fname, &fname_len, &alias) == FAILURE) { RETURN_THROWS(); } phar_request_initialize(); - RETVAL_BOOL(phar_open_from_filename(fname, fname_len, alias, alias_len, REPORT_ERRORS, NULL, &error) == SUCCESS); + RETVAL_BOOL(phar_open_from_filename(fname, fname_len, alias, REPORT_ERRORS, NULL, &error) == SUCCESS); if (error) { zend_throw_exception_ex(phar_ce_PharException, 0, "%s", error); @@ -1069,7 +1071,7 @@ static const spl_other_handler phar_spl_foreign_handler = { */ PHP_METHOD(Phar, __construct) { - char *fname, *alias = NULL, *error, *save_fname; + char *fname, *error, *save_fname; size_t fname_len, alias_len = 0; bool is_data; zend_long flags = SPL_FILE_DIR_SKIPDOTS|SPL_FILE_DIR_UNIXPATHS; @@ -1077,17 +1079,18 @@ PHP_METHOD(Phar, __construct) phar_archive_object *phar_obj; phar_archive_data *phar_data; zval arg1, arg2; + zend_string *alias = NULL; phar_obj = PHAR_FETCH_INTERNAL(); is_data = instanceof_function(Z_OBJCE_P(ZEND_THIS), phar_ce_data); if (is_data) { - if (zend_parse_parameters(ZEND_NUM_ARGS(), "p|ls!l", &fname, &fname_len, &flags, &alias, &alias_len, &format) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "p|lS!l", &fname, &fname_len, &flags, &alias, &format) == FAILURE) { RETURN_THROWS(); } } else { - if (zend_parse_parameters(ZEND_NUM_ARGS(), "p|ls!", &fname, &fname_len, &flags, &alias, &alias_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "p|lS!", &fname, &fname_len, &flags, &alias) == FAILURE) { RETURN_THROWS(); } } @@ -1108,7 +1111,7 @@ PHP_METHOD(Phar, __construct) fname_len = ZSTR_LEN(arch); } - if (phar_open_or_create_filename(fname, fname_len, alias, alias_len, is_data, REPORT_ERRORS, &phar_data, &error) == FAILURE) { + if (phar_open_or_create_filename(fname, fname_len, alias, is_data, REPORT_ERRORS, &phar_data, &error) == FAILURE) { if (arch && fname == ZSTR_VAL(arch) && fname != save_fname) { zend_string_release_ex(arch, false); @@ -1256,7 +1259,7 @@ PHP_METHOD(Phar, unlinkArchive) RETURN_THROWS(); } - if (FAILURE == phar_open_from_filename(fname, fname_len, NULL, 0, REPORT_ERRORS, &phar, &error)) { + if (FAILURE == phar_open_from_filename(fname, fname_len, NULL, REPORT_ERRORS, &phar, &error)) { if (error) { zend_throw_exception_ex(phar_ce_PharException, 0, "Unknown phar archive \"%s\": %s", fname, error); efree(error); @@ -2122,12 +2125,13 @@ static zend_object *phar_rename_archive(phar_archive_data **sphar, char *ext) /* if (phar->alias && phar != pphar) { if (phar->is_temporary_alias) { phar->alias = NULL; - phar->alias_len = 0; } else { - phar->alias = pestrndup(newpath, strlen(newpath), phar->is_persistent); - phar->alias_len = strlen(newpath); + phar->alias = zend_string_init(newpath, strlen(newpath), phar->is_persistent); phar->is_temporary_alias = 1; zend_hash_str_update_ptr(&(PHAR_G(phar_alias_map)), newpath, phar->fname_len, phar); + if(phar->is_persistent){ + GC_MAKE_PERSISTENT_LOCAL(phar->alias); + } } } @@ -2142,7 +2146,6 @@ static zend_object *phar_rename_archive(phar_archive_data **sphar, char *ext) /* /* See comment in other branch. */ if (phar != pphar) { phar->alias = NULL; - phar->alias_len = 0; } } @@ -2628,8 +2631,11 @@ PHP_METHOD(Phar, getAlias) PHAR_ARCHIVE_OBJECT(); - if (phar_obj->archive->alias && phar_obj->archive->alias != phar_obj->archive->fname) { - RETURN_STRINGL(phar_obj->archive->alias, phar_obj->archive->alias_len); + if (phar_obj->archive->alias) { + if (GC_FLAGS(phar_obj->archive->alias) & GC_PERSISTENT) { + RETURN_STR(zend_string_dup(phar_obj->archive->alias, false)); + } + RETURN_STR_COPY(phar_obj->archive->alias); } } /* }}} */ @@ -2650,10 +2656,9 @@ PHP_METHOD(Phar, getPath) */ PHP_METHOD(Phar, setAlias) { - zend_string *new_alias = NULL; - char *error, *oldalias; + zend_string *new_alias = NULL, *oldalias = NULL; + char *error; phar_archive_data *fd_ptr; - size_t oldalias_len; bool old_temp, readd = false; if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &new_alias) == FAILURE) { @@ -2684,7 +2689,7 @@ PHP_METHOD(Phar, setAlias) RETURN_THROWS(); } - if (zend_string_equals_cstr(new_alias, phar_obj->archive->alias, phar_obj->archive->alias_len)) { + if (phar_obj->archive->alias && zend_string_equals(new_alias, phar_obj->archive->alias)) { RETURN_TRUE; } if (NULL != (fd_ptr = zend_hash_find_ptr(&(PHAR_G(phar_alias_map)), new_alias))) { @@ -2701,20 +2706,24 @@ PHP_METHOD(Phar, setAlias) zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", phar_obj->archive->fname); RETURN_THROWS(); } - if (phar_obj->archive->alias_len && NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), phar_obj->archive->alias, phar_obj->archive->alias_len))) { - zend_hash_str_del(&(PHAR_G(phar_alias_map)), phar_obj->archive->alias, phar_obj->archive->alias_len); + if (phar_obj->archive->alias && zend_hash_del(&(PHAR_G(phar_alias_map)), phar_obj->archive->alias) == SUCCESS) { readd = true; } ZEND_ASSERT(!phar_obj->archive->is_persistent); oldalias = phar_obj->archive->alias; - oldalias_len = phar_obj->archive->alias_len; old_temp = phar_obj->archive->is_temporary_alias; - phar_obj->archive->alias_len = ZSTR_LEN(new_alias); - if (phar_obj->archive->alias_len) { - phar_obj->archive->alias = estrndup(ZSTR_VAL(new_alias), ZSTR_LEN(new_alias)); + if (ZSTR_LEN(new_alias)) { + if (phar_obj->archive->is_persistent) { + phar_obj->archive->alias = zend_string_init(ZSTR_VAL(new_alias), ZSTR_LEN(new_alias), phar_obj->archive->is_persistent); + if(phar_obj->archive->is_persistent){ + GC_MAKE_PERSISTENT_LOCAL(phar_obj->archive->alias); + } + } else { + phar_obj->archive->alias = zend_string_copy(new_alias); + } } else { phar_obj->archive->alias = NULL; } @@ -2723,13 +2732,12 @@ PHP_METHOD(Phar, setAlias) phar_flush(phar_obj->archive, &error); if (error) { - efree(phar_obj->archive->alias); + zend_string_release_ex(phar_obj->archive->alias, 0); phar_obj->archive->alias = oldalias; - phar_obj->archive->alias_len = oldalias_len; phar_obj->archive->is_temporary_alias = old_temp; zend_throw_exception_ex(phar_ce_PharException, 0, "%s", error); if (readd) { - zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), oldalias, oldalias_len, phar_obj->archive); + zend_hash_add_ptr(&(PHAR_G(phar_alias_map)), oldalias, phar_obj->archive); } efree(error); RETURN_THROWS(); @@ -2738,7 +2746,7 @@ PHP_METHOD(Phar, setAlias) zend_hash_add_ptr(&(PHAR_G(phar_alias_map)), new_alias, phar_obj->archive); if (oldalias) { - efree(oldalias); + zend_string_release_ex(oldalias, 0); } RETURN_TRUE; @@ -4406,7 +4414,7 @@ PHP_METHOD(PharFileInfo, __construct) RETURN_THROWS(); } - if (phar_open_from_filename(ZSTR_VAL(arch), ZSTR_LEN(arch), NULL, 0, REPORT_ERRORS, &phar_data, &error) == FAILURE) { + if (phar_open_from_filename(ZSTR_VAL(arch), ZSTR_LEN(arch), NULL, REPORT_ERRORS, &phar_data, &error) == FAILURE) { zend_string_release_ex(arch, false); efree(entry); if (error) { @@ -4446,6 +4454,7 @@ PHP_METHOD(PharFileInfo, __construct) zend_call_known_instance_method_with_1_params(spl_ce_SplFileInfo->constructor, Z_OBJ_P(ZEND_THIS), NULL, &arg1); + zval_ptr_dtor(&arg1); } /* }}} */ diff --git a/ext/phar/stream.c b/ext/phar/stream.c index 455f403b597b..55e29cb67eeb 100644 --- a/ext/phar/stream.c +++ b/ext/phar/stream.c @@ -114,7 +114,7 @@ php_url* phar_parse_url(php_stream_wrapper *wrapper, const char *filename, const php_url_free(resource); return NULL; } - if (phar_open_or_create_filename(ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), NULL, 0, 0, options, &phar, &error) == FAILURE) + if (phar_open_or_create_filename(ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), NULL, 0, options, &phar, &error) == FAILURE) { if (error) { if (!(options & PHP_STREAM_URL_STAT_QUIET)) { @@ -137,7 +137,7 @@ php_url* phar_parse_url(php_stream_wrapper *wrapper, const char *filename, const return NULL; } } else { - if (phar_open_from_filename(ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), NULL, 0, options, NULL, &error) == FAILURE) + if (phar_open_from_filename(ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), NULL, options, NULL, &error) == FAILURE) { if (error) { if (!(options & PHP_STREAM_URL_STAT_QUIET)) { @@ -233,7 +233,7 @@ static php_stream * phar_wrapper_open_url(php_stream_wrapper *wrapper, const cha } else { if (!*internal_file && (options & STREAM_OPEN_FOR_INCLUDE)) { /* retrieve the stub */ - if (FAILURE == phar_get_archive(&phar, ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), NULL, 0, NULL)) { + if (FAILURE == phar_get_archive(&phar, ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), NULL, NULL)) { php_stream_wrapper_log_error(wrapper, options, "file %s is not a valid phar archive", ZSTR_VAL(resource->host)); efree(internal_file); php_url_free(resource); @@ -581,7 +581,7 @@ static int phar_wrapper_stat(php_stream_wrapper *wrapper, const char *url, int f internal_file = ZSTR_VAL(resource->path) + 1; /* strip leading "/" */ /* find the phar in our trusty global hash indexed by alias (host of phar://blah.phar/file.whatever) */ - if (FAILURE == phar_get_archive(&phar, ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), NULL, 0, NULL)) { + if (FAILURE == phar_get_archive(&phar, ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), NULL, NULL)) { php_url_free(resource); return FAILURE; } @@ -741,7 +741,7 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from php_error_docref(NULL, E_WARNING, "phar error: cannot rename \"%s\" to \"%s\": invalid or non-writable url \"%s\"", url_from, url_to, url_from); return 0; } - if (SUCCESS != phar_get_archive(&pfrom, ZSTR_VAL(resource_from->host), ZSTR_LEN(resource_from->host), NULL, 0, &error)) { + if (SUCCESS != phar_get_archive(&pfrom, ZSTR_VAL(resource_from->host), ZSTR_LEN(resource_from->host), NULL, &error)) { pfrom = NULL; if (error) { efree(error); @@ -758,7 +758,7 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from php_error_docref(NULL, E_WARNING, "phar error: cannot rename \"%s\" to \"%s\": invalid or non-writable url \"%s\"", url_from, url_to, url_to); return 0; } - if (SUCCESS != phar_get_archive(&pto, ZSTR_VAL(resource_to->host), ZSTR_LEN(resource_to->host), NULL, 0, &error)) { + if (SUCCESS != phar_get_archive(&pto, ZSTR_VAL(resource_to->host), ZSTR_LEN(resource_to->host), NULL, &error)) { if (error) { efree(error); } @@ -807,7 +807,7 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from return 0; } - if (SUCCESS != phar_get_archive(&phar, ZSTR_VAL(resource_from->host), ZSTR_LEN(resource_from->host), NULL, 0, &error)) { + if (SUCCESS != phar_get_archive(&phar, ZSTR_VAL(resource_from->host), ZSTR_LEN(resource_from->host), NULL, &error)) { php_url_free(resource_from); php_url_free(resource_to); php_error_docref(NULL, E_WARNING, "phar error: cannot rename \"%s\" to \"%s\": %s", url_from, url_to, error); diff --git a/ext/phar/tar.c b/ext/phar/tar.c index ef356bfc7a28..5c1f9ac9b966 100644 --- a/ext/phar/tar.c +++ b/ext/phar/tar.c @@ -126,10 +126,10 @@ bool phar_is_tar(const char *buf, const char *fname) /* {{{ */ } /* }}} */ -ZEND_ATTRIBUTE_NONNULL_ARGS(1, 7, 8) zend_result phar_open_or_create_tar(char *fname, size_t fname_len, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ +ZEND_ATTRIBUTE_NONNULL_ARGS(1, 6, 7) zend_result phar_open_or_create_tar(char *fname, size_t fname_len, zend_string *alias, bool is_data, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ { phar_archive_data *phar; - zend_result ret = phar_create_or_parse_filename(fname, fname_len, alias, alias_len, is_data, options, &phar, error); + zend_result ret = phar_create_or_parse_filename(fname, fname_len, alias, is_data, options, &phar, error); if (FAILURE == ret) { return FAILURE; @@ -197,9 +197,9 @@ static zend_result phar_tar_process_metadata(phar_entry_info *entry, php_stream } /* }}} */ -zend_result phar_parse_tarfile(php_stream* fp, const char *fname, size_t fname_len, const char *alias, size_t alias_len, phar_archive_data** pphar, uint32_t compression, char **error) /* {{{ */ +zend_result phar_parse_tarfile(php_stream* fp, const char *fname, size_t fname_len, zend_string *alias, phar_archive_data** pphar, uint32_t compression, char **error) /* {{{ */ { - char buf[512], *actual_alias = NULL, *p; + char buf[512], *p; phar_entry_info entry = {0}; size_t pos = 0, read, totalsize; tar_header *hdr; @@ -207,6 +207,7 @@ zend_result phar_parse_tarfile(php_stream* fp, const char *fname, size_t fname_l phar_archive_data *myphar, *actual; bool last_was_longlink = false; size_t linkname_len; + zend_string *actual_alias = NULL; if (error) { *error = NULL; @@ -285,6 +286,9 @@ zend_result phar_parse_tarfile(php_stream* fp, const char *fname, size_t fname_l } bail: php_stream_close(fp); + if (actual_alias) { + zend_string_release_ex(actual_alias, myphar->is_persistent); + } phar_destroy_phar_data(myphar); return FAILURE; } @@ -325,6 +329,9 @@ zend_result phar_parse_tarfile(php_stream* fp, const char *fname, size_t fname_l spprintf(error, 4096, "phar error: \"%s\" is a corrupted tar file (truncated)", fname); } php_stream_close(fp); + if (actual_alias) { + zend_string_release_ex(actual_alias, myphar->is_persistent); + } phar_destroy_phar_data(myphar); return FAILURE; } @@ -337,6 +344,9 @@ zend_result phar_parse_tarfile(php_stream* fp, const char *fname, size_t fname_l spprintf(error, 4096, "phar error: \"%s\" is a corrupted tar file (truncated)", fname); } php_stream_close(fp); + if (actual_alias) { + zend_string_release_ex(actual_alias, myphar->is_persistent); + } phar_destroy_phar_data(myphar); return FAILURE; } @@ -365,6 +375,9 @@ zend_result phar_parse_tarfile(php_stream* fp, const char *fname, size_t fname_l spprintf(error, 4096, "phar error: \"%s\" is a corrupted tar file (invalid entry size)", fname); } php_stream_close(fp); + if (actual_alias) { + zend_string_release_ex(actual_alias, myphar->is_persistent); + } phar_destroy_phar_data(myphar); return FAILURE; } @@ -381,6 +394,9 @@ zend_result phar_parse_tarfile(php_stream* fp, const char *fname, size_t fname_l spprintf(error, 4096, "phar error: \"%s\" is a corrupted tar file (truncated)", fname); } php_stream_close(fp); + if (actual_alias) { + zend_string_release_ex(actual_alias, myphar->is_persistent); + } phar_destroy_phar_data(myphar); return FAILURE; } @@ -396,6 +412,9 @@ zend_result phar_parse_tarfile(php_stream* fp, const char *fname, size_t fname_l spprintf(error, 4096, "phar error: \"%s\" is a corrupted tar file (truncated)", fname); } php_stream_close(fp); + if (actual_alias) { + zend_string_release_ex(actual_alias, myphar->is_persistent); + } phar_destroy_phar_data(myphar); return FAILURE; } @@ -408,6 +427,9 @@ zend_result phar_parse_tarfile(php_stream* fp, const char *fname, size_t fname_l spprintf(error, 4096, "phar error: \"%s\" is a corrupted tar file (truncated)", fname); } php_stream_close(fp); + if (actual_alias) { + zend_string_release_ex(actual_alias, myphar->is_persistent); + } phar_destroy_phar_data(myphar); return FAILURE; } @@ -470,6 +492,9 @@ zend_result phar_parse_tarfile(php_stream* fp, const char *fname, size_t fname_l } zend_string_release_ex(entry.filename, myphar->is_persistent); php_stream_close(fp); + if (actual_alias) { + zend_string_release_ex(actual_alias, myphar->is_persistent); + } phar_destroy_phar_data(myphar); return FAILURE; } @@ -503,6 +528,9 @@ zend_result phar_parse_tarfile(php_stream* fp, const char *fname, size_t fname_l } zend_string_release_ex(entry.filename, myphar->is_persistent); php_stream_close(fp); + if (actual_alias) { + zend_string_release_ex(actual_alias, myphar->is_persistent); + } phar_destroy_phar_data(myphar); return FAILURE; } @@ -525,6 +553,9 @@ zend_result phar_parse_tarfile(php_stream* fp, const char *fname, size_t fname_l spprintf(error, 4096, "phar error: tar-based phar \"%s\" has invalid metadata in magic file \"%s\"", fname, ZSTR_VAL(entry.filename)); } php_stream_close(fp); + if (actual_alias) { + zend_string_release_ex(actual_alias, myphar->is_persistent); + } phar_destroy_phar_data(myphar); return FAILURE; } @@ -537,6 +568,9 @@ zend_result phar_parse_tarfile(php_stream* fp, const char *fname, size_t fname_l spprintf(error, 4096, "phar error: tar-based phar \"%s\" has alias that is larger than 511 bytes, cannot process", fname); } php_stream_close(fp); + if (actual_alias) { + zend_string_release_ex(actual_alias, myphar->is_persistent); + } phar_destroy_phar_data(myphar); return FAILURE; } @@ -558,20 +592,26 @@ zend_result phar_parse_tarfile(php_stream* fp, const char *fname, size_t fname_l } php_stream_close(fp); + if (actual_alias) { + zend_string_release_ex(actual_alias, myphar->is_persistent); + } phar_destroy_phar_data(myphar); return FAILURE; } - actual_alias = pestrndup(buf, size, myphar->is_persistent); - myphar->alias = actual_alias; - myphar->alias_len = size; + actual_alias = zend_string_init(buf, size, myphar->is_persistent); + if (myphar->is_persistent) { + GC_MAKE_PERSISTENT_LOCAL(actual_alias); + } php_stream_seek(fp, pos, SEEK_SET); } else { if (error) { spprintf(error, 4096, "phar error: Unable to read alias from tar-based phar \"%s\"", fname); } - php_stream_close(fp); + if (actual_alias) { + zend_string_release_ex(actual_alias, myphar->is_persistent); + } phar_destroy_phar_data(myphar); return FAILURE; } @@ -588,6 +628,9 @@ zend_result phar_parse_tarfile(php_stream* fp, const char *fname, size_t fname_l spprintf(error, 4096, "phar error: \"%s\" is a corrupted tar file (truncated)", fname); } php_stream_close(fp); + if (actual_alias) { + zend_string_release_ex(actual_alias, myphar->is_persistent); + } phar_destroy_phar_data(myphar); return FAILURE; } @@ -605,6 +648,9 @@ zend_result phar_parse_tarfile(php_stream* fp, const char *fname, size_t fname_l spprintf(error, 4096, "phar error: \"%s\" is a corrupted tar file (truncated)", fname); } php_stream_close(fp); + if (actual_alias) { + zend_string_release_ex(actual_alias, myphar->is_persistent); + } phar_destroy_phar_data(myphar); return FAILURE; } @@ -619,6 +665,9 @@ zend_result phar_parse_tarfile(php_stream* fp, const char *fname, size_t fname_l /* ensure signature set */ if (!myphar->is_data && PHAR_G(require_hash) && !myphar->signature) { php_stream_close(fp); + if (actual_alias) { + zend_string_release_ex(actual_alias, myphar->is_persistent); + } phar_destroy_phar_data(myphar); if (error) { spprintf(error, 0, "tar-based phar \"%s\" does not have a signature", fname); @@ -651,6 +700,9 @@ zend_result phar_parse_tarfile(php_stream* fp, const char *fname, size_t fname_l spprintf(error, 4096, "phar error: Unable to add tar-based phar \"%s\" to phar registry", fname); } php_stream_close(fp); + if (actual_alias) { + zend_string_release_ex(actual_alias, myphar->is_persistent); + } phar_destroy_phar_data(myphar); return FAILURE; } @@ -662,22 +714,26 @@ zend_result phar_parse_tarfile(php_stream* fp, const char *fname, size_t fname_l myphar->is_temporary_alias = 0; - if (NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), actual_alias, myphar->alias_len))) { + if (NULL != (fd_ptr = zend_hash_find_ptr(&(PHAR_G(phar_alias_map)), actual_alias))) { if (SUCCESS != phar_free_alias(fd_ptr)) { if (error) { spprintf(error, 4096, "phar error: Unable to add tar-based phar \"%s\", alias is already in use", fname); } zend_hash_str_del(&(PHAR_G(phar_fname_map)), myphar->fname, fname_len); + zend_string_release_ex(actual_alias, myphar->is_persistent); return FAILURE; } } - - zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), actual_alias, myphar->alias_len, myphar); + + myphar->alias = actual_alias; + zend_hash_add_ptr(&(PHAR_G(phar_alias_map)), actual_alias, myphar); + zend_string_release_ex(actual_alias, myphar->is_persistent); + } else { phar_archive_data *fd_ptr; - if (alias_len) { - if (NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len))) { + if (alias && ZSTR_LEN(alias)) { + if (NULL != (fd_ptr = zend_hash_find_ptr(&(PHAR_G(phar_alias_map)), alias))) { if (SUCCESS != phar_free_alias(fd_ptr)) { if (error) { spprintf(error, 4096, "phar error: Unable to add tar-based phar \"%s\", alias is already in use", fname); @@ -686,12 +742,13 @@ zend_result phar_parse_tarfile(php_stream* fp, const char *fname, size_t fname_l return FAILURE; } } - zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len, myphar); - myphar->alias = pestrndup(alias, alias_len, myphar->is_persistent); - myphar->alias_len = alias_len; + myphar->alias = zend_string_init(ZSTR_VAL(alias), ZSTR_LEN(alias), myphar->is_persistent); + zend_hash_add_ptr(&(PHAR_G(phar_alias_map)), myphar->alias, myphar); } else { - myphar->alias = pestrndup(myphar->fname, fname_len, myphar->is_persistent); - myphar->alias_len = fname_len; + myphar->alias = zend_string_init(myphar->fname, fname_len, myphar->is_persistent); + } + if (myphar->is_persistent) { + GC_MAKE_PERSISTENT_LOCAL(myphar->alias); } myphar->is_temporary_alias = 1; @@ -992,19 +1049,19 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_tar_flush(phar_archive_data *phar, ze } /* set alias */ - if (!phar->is_temporary_alias && phar->alias_len) { + if (!phar->is_temporary_alias && phar) { entry.fp = php_stream_fopen_tmpfile(); if (entry.fp == NULL) { *error = estrdup("phar error: unable to create temporary file"); return EOF; } - if (phar->alias_len != php_stream_write(entry.fp, phar->alias, phar->alias_len)) { + if (ZSTR_LEN(phar->alias) != php_stream_write(entry.fp, ZSTR_VAL(phar->alias), ZSTR_LEN(phar->alias))) { spprintf(error, 0, "unable to set alias in tar-based phar \"%s\"", phar->fname); php_stream_close(entry.fp); return EOF; } - entry.uncompressed_filesize = phar->alias_len; + entry.uncompressed_filesize = ZSTR_LEN(phar->alias); entry.filename = ZSTR_INIT_LITERAL(".phar/alias.txt", false); zend_hash_update_mem(&phar->manifest, entry.filename, &entry, sizeof(phar_entry_info)); diff --git a/ext/phar/util.c b/ext/phar/util.c index 43ed4dd24824..a4bb5110c2ed 100644 --- a/ext/phar/util.c +++ b/ext/phar/util.c @@ -308,7 +308,7 @@ zend_string *phar_find_in_include_path(zend_string *filename, phar_archive_data } if (*ZSTR_VAL(filename) == '.') { - if (FAILURE == phar_get_archive(&phar, ZSTR_VAL(arch), ZSTR_LEN(arch), NULL, 0, NULL)) { + if (FAILURE == phar_get_archive(&phar, ZSTR_VAL(arch), ZSTR_LEN(arch), NULL, NULL)) { zend_string_release_ex(arch, false); return NULL; } @@ -478,7 +478,7 @@ ZEND_ATTRIBUTE_NONNULL zend_result phar_get_entry_data(phar_entry_data **ret, co *ret = NULL; *error = NULL; - if (FAILURE == phar_get_archive(&phar, fname, fname_len, NULL, 0, error)) { + if (FAILURE == phar_get_archive(&phar, fname, fname_len, NULL, error)) { return FAILURE; } @@ -623,7 +623,7 @@ ZEND_ATTRIBUTE_NONNULL phar_entry_data *phar_get_or_create_entry_data(char *fnam is_dir = (path_len && path[path_len - 1] == '/') ? 1 : 0; - if (FAILURE == phar_get_archive(&phar, fname, fname_len, NULL, 0, error)) { + if (FAILURE == phar_get_archive(&phar, fname, fname_len, NULL, error)) { return NULL; } @@ -957,7 +957,7 @@ zend_result phar_free_alias(const phar_archive_data *phar) /* {{{ */ * Looks up a phar archive in the filename map, connecting it to the alias * (if any) or returns null */ -zend_result phar_get_archive(phar_archive_data **archive, const char *fname, size_t fname_len, const char *alias, size_t alias_len, char **error) /* {{{ */ +zend_result phar_get_archive(phar_archive_data **archive, const char *fname, size_t fname_len, zend_string *alias, char **error) /* {{{ */ { phar_archive_data *fd, *fd_ptr; char *my_realpath; @@ -972,40 +972,39 @@ zend_result phar_get_archive(phar_archive_data **archive, const char *fname, siz if (PHAR_G(last_phar) && fname_len == PHAR_G(last_phar_name_len) && !memcmp(fname, PHAR_G(last_phar_name), fname_len)) { *archive = PHAR_G(last_phar); - if (alias && alias_len) { + if (alias) { - if (!PHAR_G(last_phar)->is_temporary_alias && (alias_len != PHAR_G(last_phar)->alias_len || memcmp(PHAR_G(last_phar)->alias, alias, alias_len))) { + if (!PHAR_G(last_phar)->is_temporary_alias && !zend_string_equals(PHAR_G(last_phar)->alias, alias)) { if (error) { - spprintf(error, 0, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, PHAR_G(last_phar)->fname, fname); + spprintf(error, 0, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", ZSTR_VAL(alias), PHAR_G(last_phar)->fname, fname); } *archive = NULL; return FAILURE; } - if (PHAR_G(last_phar)->alias_len && NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), PHAR_G(last_phar)->alias, PHAR_G(last_phar)->alias_len))) { - zend_hash_str_del(&(PHAR_G(phar_alias_map)), PHAR_G(last_phar)->alias, PHAR_G(last_phar)->alias_len); + if (PHAR_G(last_phar)->alias) { + zend_hash_del(&(PHAR_G(phar_alias_map)), PHAR_G(last_phar)->alias); } - zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len, *archive); + zend_hash_add_ptr(&(PHAR_G(phar_alias_map)), alias, *archive); PHAR_G(last_alias) = alias; - PHAR_G(last_alias_len) = alias_len; } return SUCCESS; } - if (alias && alias_len && PHAR_G(last_phar) && alias_len == PHAR_G(last_alias_len) && !memcmp(alias, PHAR_G(last_alias), alias_len)) { + if (alias && PHAR_G(last_phar) && PHAR_G(last_alias) && zend_string_equals(alias, PHAR_G(last_alias))) { fd = PHAR_G(last_phar); fd_ptr = fd; goto alias_success; } - if (alias && alias_len) { - if (NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len))) { + if (alias) { + if (NULL != (fd_ptr = zend_hash_find_ptr(&(PHAR_G(phar_alias_map)), alias))) { alias_success: if (fname && (fname_len != fd_ptr->fname_len || strncmp(fname, fd_ptr->fname, fname_len))) { if (error) { - spprintf(error, 0, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, fd_ptr->fname, fname); + spprintf(error, 0, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", ZSTR_VAL(alias), fd_ptr->fname, fname); } if (SUCCESS == phar_free_alias(fd_ptr)) { if (error) { @@ -1022,12 +1021,11 @@ zend_result phar_get_archive(phar_archive_data **archive, const char *fname, siz PHAR_G(last_phar_name) = fd->fname; PHAR_G(last_phar_name_len) = fd->fname_len; PHAR_G(last_alias) = alias; - PHAR_G(last_alias_len) = alias_len; return SUCCESS; } - if (PHAR_G(manifest_cached) && NULL != (fd_ptr = zend_hash_str_find_ptr(&cached_alias, alias, alias_len))) { + if (PHAR_G(manifest_cached) && NULL != (fd_ptr = zend_hash_find_ptr(&cached_alias, alias))) { goto alias_success; } } @@ -1041,26 +1039,25 @@ zend_result phar_get_archive(phar_archive_data **archive, const char *fname, siz *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 (alias) { + if (!fd->is_temporary_alias && !zend_string_equals(alias, fd->alias)) { if (error) { - spprintf(error, 0, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, fd_ptr->fname, fname); + spprintf(error, 0, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", ZSTR_VAL(alias), fd_ptr->fname, fname); } return FAILURE; } - if (fd->alias_len && NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), fd->alias, fd->alias_len))) { - zend_hash_str_del(&(PHAR_G(phar_alias_map)), fd->alias, fd->alias_len); + if (fd->alias) { + zend_hash_del(&(PHAR_G(phar_alias_map)), fd->alias); } - zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len, fd); + zend_hash_add_ptr(&(PHAR_G(phar_alias_map)), alias, fd); } PHAR_G(last_phar) = fd; PHAR_G(last_phar_name) = fd->fname; PHAR_G(last_phar_name_len) = fd->fname_len; PHAR_G(last_alias) = fd->alias; - PHAR_G(last_alias_len) = fd->alias_len; return SUCCESS; } @@ -1071,10 +1068,10 @@ zend_result phar_get_archive(phar_archive_data **archive, const char *fname, siz /* this could be problematic - alias should never be different from manifest alias for cached phars */ - if (!fd->is_temporary_alias && alias && alias_len) { - if (alias_len != fd->alias_len || memcmp(fd->alias, alias, alias_len)) { + if (!fd->is_temporary_alias && alias) { + if (!zend_string_equals(alias, fd->alias)) { if (error) { - spprintf(error, 0, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, fd_ptr->fname, fname); + spprintf(error, 0, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", ZSTR_VAL(alias), fd_ptr->fname, fname); } return FAILURE; } @@ -1084,7 +1081,6 @@ zend_result phar_get_archive(phar_archive_data **archive, const char *fname, siz PHAR_G(last_phar_name) = fd->fname; PHAR_G(last_phar_name_len) = fd->fname_len; PHAR_G(last_alias) = fd->alias; - PHAR_G(last_alias_len) = fd->alias_len; return SUCCESS; } @@ -1096,7 +1092,6 @@ zend_result phar_get_archive(phar_archive_data **archive, const char *fname, siz PHAR_G(last_phar_name) = fd->fname; PHAR_G(last_phar_name_len) = fd->fname_len; PHAR_G(last_alias) = fd->alias; - PHAR_G(last_alias_len) = fd->alias_len; return SUCCESS; } @@ -1108,7 +1103,6 @@ zend_result phar_get_archive(phar_archive_data **archive, const char *fname, siz PHAR_G(last_phar_name) = fd->fname; PHAR_G(last_phar_name_len) = fd->fname_len; PHAR_G(last_alias) = fd->alias; - PHAR_G(last_alias_len) = fd->alias_len; return SUCCESS; } @@ -1132,8 +1126,8 @@ zend_result phar_get_archive(phar_archive_data **archive, const char *fname, siz *archive = fd_ptr; fd = fd_ptr; - if (alias && alias_len) { - zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len, fd); + if (alias) { + zend_hash_add_ptr(&(PHAR_G(phar_alias_map)), alias, fd); } efree(my_realpath); @@ -1142,7 +1136,6 @@ zend_result phar_get_archive(phar_archive_data **archive, const char *fname, siz PHAR_G(last_phar_name) = fd->fname; PHAR_G(last_phar_name_len) = fd->fname_len; PHAR_G(last_alias) = fd->alias; - PHAR_G(last_alias_len) = fd->alias_len; return SUCCESS; } @@ -2035,7 +2028,7 @@ static void phar_copy_cached_phar(phar_archive_data **pphar) /* {{{ */ phar->ext = phar->fname + (phar->ext - fname); if (phar->alias) { - phar->alias = estrndup(phar->alias, phar->alias_len); + zend_string_addref(phar->alias); } if (phar->signature) { @@ -2082,7 +2075,7 @@ zend_result phar_copy_on_write(phar_archive_data **pphar) /* {{{ */ PHAR_G(last_alias) = NULL; PHAR_G(last_phar_name) = NULL; - if (newpphar->alias_len && NULL == zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), newpphar->alias, newpphar->alias_len, newpphar)) { + if (newpphar->alias && NULL == zend_hash_add_ptr(&(PHAR_G(phar_alias_map)), newpphar->alias, newpphar)) { zend_hash_str_del(&(PHAR_G(phar_fname_map)), (*pphar)->fname, (*pphar)->fname_len); return FAILURE; } diff --git a/ext/phar/zip.c b/ext/phar/zip.c index f757adc90c88..bca347771a96 100644 --- a/ext/phar/zip.c +++ b/ext/phar/zip.c @@ -224,7 +224,7 @@ static char *phar_find_eocd(const char *s, size_t n) * This is used by phar_open_from_fp to process a zip-based phar, but can be called * directly. */ -zend_result phar_parse_zipfile(php_stream *fp, const char *fname, size_t fname_len, const char *alias, size_t alias_len, phar_archive_data** pphar, char **error) /* {{{ */ +zend_result phar_parse_zipfile(php_stream *fp, const char *fname, size_t fname_len, zend_string *alias, phar_archive_data** pphar, char **error) /* {{{ */ { phar_zip_dir_end locator; char buf[sizeof(locator) + 65536]; @@ -232,9 +232,9 @@ zend_result phar_parse_zipfile(php_stream *fp, const char *fname, size_t fname_l uint16_t i; phar_archive_data *mydata = NULL; phar_entry_info entry = {0}; - char *ext, *actual_alias = NULL; + char *ext = NULL; char *metadata = NULL; - + zend_string *actual_alias = NULL; size = php_stream_tell(fp); if (size > sizeof(locator) + 65536) { @@ -341,7 +341,6 @@ zend_result phar_parse_zipfile(php_stream *fp, const char *fname, size_t fname_l entry.fp_type = PHAR_FP; entry.is_persistent = mydata->is_persistent; #define PHAR_ZIP_FAIL(errmsg) \ - efree(actual_alias); \ zend_hash_destroy(&mydata->manifest); \ HT_INVALIDATE(&mydata->manifest); \ zend_hash_destroy(&mydata->mounted_dirs); \ @@ -615,7 +614,6 @@ zend_result phar_parse_zipfile(php_stream *fp, const char *fname, size_t fname_l zend_off_t restore_pos = php_stream_tell(fp); php_stream_seek(fp, entry.offset, 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)); @@ -626,20 +624,8 @@ zend_result phar_parse_zipfile(php_stream *fp, const char *fname, size_t fname_l php_stream_filter_append(&fp->readfilters, filter); - // TODO: refactor to avoid reallocation ??? -//??? entry.uncompressed_filesize = php_stream_copy_to_mem(fp, &actual_alias, entry.uncompressed_filesize, 0) - { - zend_string *str = php_stream_copy_to_mem(fp, entry.uncompressed_filesize, 0); - if (str) { - entry.uncompressed_filesize = ZSTR_LEN(str); - actual_alias = estrndup(ZSTR_VAL(str), ZSTR_LEN(str)); - zend_string_release_ex(str, 0); - } else { - actual_alias = NULL; - entry.uncompressed_filesize = 0; - } - } - + actual_alias = php_stream_copy_to_mem(fp, entry.uncompressed_filesize, 0); + entry.uncompressed_filesize = actual_alias ? ZSTR_LEN(actual_alias) : 0; if (!entry.uncompressed_filesize) { php_stream_filter_remove(filter, 1); zend_string_release_ex(entry.filename, entry.is_persistent); @@ -658,21 +644,9 @@ zend_result phar_parse_zipfile(php_stream *fp, const char *fname, size_t fname_l } php_stream_filter_append(&fp->readfilters, filter); - - // TODO: refactor to avoid reallocation ??? -//??? entry.uncompressed_filesize = php_stream_copy_to_mem(fp, &actual_alias, entry.uncompressed_filesize, 0) - { - zend_string *str = php_stream_copy_to_mem(fp, entry.uncompressed_filesize, 0); - if (str) { - entry.uncompressed_filesize = ZSTR_LEN(str); - actual_alias = estrndup(ZSTR_VAL(str), ZSTR_LEN(str)); - zend_string_release_ex(str, 0); - } else { - actual_alias = NULL; - entry.uncompressed_filesize = 0; - } - } - + actual_alias = php_stream_copy_to_mem(fp, entry.uncompressed_filesize, 0); + entry.uncompressed_filesize = actual_alias ? ZSTR_LEN(actual_alias) : 0; + printf("++++++++arrrr%s--", ZSTR_VAL(actual_alias)); if (!entry.uncompressed_filesize) { php_stream_filter_remove(filter, 1); zend_string_release_ex(entry.filename, entry.is_persistent); @@ -682,20 +656,8 @@ zend_result phar_parse_zipfile(php_stream *fp, const char *fname, size_t fname_l php_stream_filter_flush(filter, 1); php_stream_filter_remove(filter, 1); } else { - // TODO: refactor to avoid reallocation ??? -//??? entry.uncompressed_filesize = php_stream_copy_to_mem(fp, &actual_alias, entry.uncompressed_filesize, 0) - { - zend_string *str = php_stream_copy_to_mem(fp, entry.uncompressed_filesize, 0); - if (str) { - entry.uncompressed_filesize = ZSTR_LEN(str); - actual_alias = estrndup(ZSTR_VAL(str), ZSTR_LEN(str)); - zend_string_release_ex(str, 0); - } else { - actual_alias = NULL; - entry.uncompressed_filesize = 0; - } - } - + actual_alias = php_stream_copy_to_mem(fp, entry.uncompressed_filesize, 0); + entry.uncompressed_filesize = actual_alias ? ZSTR_LEN(actual_alias) : 0; if (!entry.uncompressed_filesize) { zend_string_release_ex(entry.filename, entry.is_persistent); PHAR_ZIP_FAIL("unable to read in alias, truncated"); @@ -728,40 +690,40 @@ zend_result phar_parse_zipfile(php_stream *fp, const char *fname, size_t fname_l if (actual_alias) { phar_archive_data *fd_ptr; - if (!phar_validate_alias(actual_alias, mydata->alias_len)) { + if (!phar_validate_alias(ZSTR_VAL(actual_alias), ZSTR_LEN(actual_alias))) { if (error) { - spprintf(error, 4096, "phar error: invalid alias \"%s\" in zip-based phar \"%s\"", actual_alias, fname); + spprintf(error, 4096, "phar error: invalid alias \"%s\" in zip-based phar \"%s\"", ZSTR_VAL(actual_alias), fname); } - efree(actual_alias); + zend_string_release_ex(actual_alias, 0); zend_hash_str_del(&(PHAR_G(phar_fname_map)), mydata->fname, fname_len); return FAILURE; } mydata->is_temporary_alias = 0; - if (NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), actual_alias, mydata->alias_len))) { + if (NULL != (fd_ptr = zend_hash_find_ptr(&(PHAR_G(phar_alias_map)), actual_alias))) { if (SUCCESS != phar_free_alias(fd_ptr)) { 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_string_release_ex(actual_alias, 0); zend_hash_str_del(&(PHAR_G(phar_fname_map)), mydata->fname, fname_len); return FAILURE; } } - mydata->alias = entry.is_persistent ? pestrndup(actual_alias, mydata->alias_len, 1) : actual_alias; - + mydata->alias = zend_string_init(ZSTR_VAL(actual_alias), ZSTR_LEN(actual_alias), entry.is_persistent); if (entry.is_persistent) { - efree(actual_alias); + GC_MAKE_PERSISTENT_LOCAL(mydata->alias); } + zend_hash_add_ptr(&(PHAR_G(phar_alias_map)), actual_alias, mydata); + zend_string_release_ex(actual_alias, 0); - zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), mydata->alias, mydata->alias_len, mydata); } else { phar_archive_data *fd_ptr; - if (alias_len) { - if (NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len))) { + if (alias && ZSTR_LEN(alias)) { + if (NULL != (fd_ptr = zend_hash_find_ptr(&(PHAR_G(phar_alias_map)), alias))) { if (SUCCESS != phar_free_alias(fd_ptr)) { if (error) { spprintf(error, 4096, "phar error: Unable to add zip-based phar \"%s\" with explicit alias, alias is already in use", fname); @@ -770,13 +732,14 @@ zend_result phar_parse_zipfile(php_stream *fp, const char *fname, size_t fname_l return FAILURE; } } - - zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len, mydata); - mydata->alias = pestrndup(alias, alias_len, mydata->is_persistent); - mydata->alias_len = alias_len; + mydata->alias = zend_string_init(ZSTR_VAL(alias), ZSTR_LEN(alias), mydata->is_persistent); + zend_hash_add_ptr(&(PHAR_G(phar_alias_map)), mydata->alias, mydata); } else { - mydata->alias = pestrndup(mydata->fname, fname_len, mydata->is_persistent); - mydata->alias_len = fname_len; + mydata->alias = zend_string_init(mydata->fname, fname_len, mydata->is_persistent); + } + + if (mydata->is_persistent) { + GC_MAKE_PERSISTENT_LOCAL(myphar->alias); } mydata->is_temporary_alias = 1; @@ -793,10 +756,10 @@ zend_result phar_parse_zipfile(php_stream *fp, const char *fname, size_t fname_l /** * Create or open a zip-based phar for writing */ -ZEND_ATTRIBUTE_NONNULL_ARGS(1, 7, 8) zend_result phar_open_or_create_zip(char *fname, size_t fname_len, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ +ZEND_ATTRIBUTE_NONNULL_ARGS(1, 6, 7) zend_result phar_open_or_create_zip(char *fname, size_t fname_len, zend_string *alias, bool is_data, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ { phar_archive_data *phar; - zend_result ret = phar_create_or_parse_filename(fname, fname_len, alias, alias_len, is_data, options, &phar, error); + zend_result ret = phar_create_or_parse_filename(fname, fname_len, alias, is_data, options, &phar, error); if (FAILURE == ret) { return FAILURE; @@ -1250,19 +1213,19 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_zip_flush(phar_archive_data *phar, ze } /* set alias */ - if (!phar->is_temporary_alias && phar->alias_len) { + if (!phar->is_temporary_alias && phar->alias) { entry.fp = php_stream_fopen_tmpfile(); if (entry.fp == NULL) { *error = estrdup("phar error: unable to create temporary file"); return EOF; } - if (phar->alias_len != php_stream_write(entry.fp, phar->alias, phar->alias_len)) { + if (ZSTR_LEN(phar->alias) != php_stream_write(entry.fp, ZSTR_VAL(phar->alias), ZSTR_LEN(phar->alias))) { php_stream_close(entry.fp); spprintf(error, 0, "unable to set alias in zip-based phar \"%s\"", phar->fname); return EOF; } - entry.uncompressed_filesize = entry.compressed_filesize = phar->alias_len; + entry.uncompressed_filesize = entry.compressed_filesize = ZSTR_LEN(phar->alias); entry.filename = ZSTR_INIT_LITERAL(".phar/alias.txt", false); zend_hash_update_mem(&phar->manifest, entry.filename, &entry, sizeof(phar_entry_info)); @@ -1271,8 +1234,8 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_zip_flush(phar_archive_data *phar, ze } /* register alias */ - if (phar->alias_len) { - if (FAILURE == phar_get_archive(&phar, phar->fname, phar->fname_len, phar->alias, phar->alias_len, error)) { + if (phar->alias) { + if (FAILURE == phar_get_archive(&phar, phar->fname, phar->fname_len, phar->alias, error)) { return EOF; } }