diff --git a/ext/phar/dirstream.c b/ext/phar/dirstream.c index c5aa292200e86..41caa212f6fab 100644 --- a/ext/phar/dirstream.c +++ b/ext/phar/dirstream.c @@ -280,7 +280,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); @@ -359,7 +359,7 @@ int phar_wrapper_mkdir(php_stream_wrapper *wrapper, const char *url_from, int mo return 0; } - if (FAILURE == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL)) { + if (FAILURE == phar_get_archive(&phar, arch, arch_len, NULL, NULL)) { phar = NULL; } @@ -388,7 +388,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); @@ -487,7 +487,7 @@ int phar_wrapper_rmdir(php_stream_wrapper *wrapper, const char *url, int options return 0; } - if (FAILURE == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL)) { + if (FAILURE == phar_get_archive(&phar, arch, arch_len, NULL, NULL)) { phar = NULL; } @@ -516,7 +516,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 f1b2b0eba1e63..415a4124f3b4f 100644 --- a/ext/phar/func_interceptors.c +++ b/ext/phar/func_interceptors.c @@ -109,7 +109,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, arch, arch_len, NULL, 0, NULL)) { + if (FAILURE == phar_get_archive(&phar, arch, arch_len, NULL, NULL)) { efree(arch); return NULL; } @@ -515,7 +515,7 @@ static void phar_file_stat(const char *filename, size_t filename_length, int typ entry = estrndup(filename, filename_length); /* fopen within phar, if :// is not in the url, then prepend phar:/// */ entry_len = filename_length; - if (FAILURE == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL)) { + if (FAILURE == phar_get_archive(&phar, arch, arch_len, NULL, NULL)) { efree(arch); efree(entry); goto skip_phar; @@ -759,7 +759,7 @@ PHP_FUNCTION(phar_is_file) /* {{{ */ /* fopen within phar, if :// is not in the url, then prepend phar:/// */ entry_len = filename_len; /* retrieving a file within the current directory, so use this if possible */ - if (SUCCESS == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL)) { + if (SUCCESS == phar_get_archive(&phar, arch, arch_len, NULL, NULL)) { phar_entry_info *etemp; entry = phar_fix_filepath(estrndup(entry, entry_len), &entry_len, 1); @@ -825,7 +825,7 @@ PHP_FUNCTION(phar_is_link) /* {{{ */ /* fopen within phar, if :// is not in the url, then prepend phar:/// */ entry_len = filename_len; /* retrieving a file within the current directory, so use this if possible */ - if (SUCCESS == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL)) { + if (SUCCESS == phar_get_archive(&phar, arch, arch_len, NULL, NULL)) { phar_entry_info *etemp; entry = phar_fix_filepath(estrndup(entry, entry_len), &entry_len, 1); diff --git a/ext/phar/phar.c b/ext/phar/phar.c index 2a32907675594..d5f7133a4f2d8 100644 --- a/ext/phar/phar.c +++ b/ext/phar/phar.c @@ -133,7 +133,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; @@ -194,8 +194,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; } @@ -258,7 +258,8 @@ bool phar_archive_delref(phar_archive_data *phar) /* {{{ */ } else if (!phar->refcount) { /* invalidate phar cache */ PHAR_G(last_phar) = NULL; - PHAR_G(last_phar_name) = PHAR_G(last_alias) = NULL; + PHAR_G(last_phar_name) = NULL; + PHAR_G(last_alias) = NULL; if (phar->fp && (!(phar->flags & PHAR_FILE_COMPRESSION_MASK) || !phar->alias)) { /* close open file handle - allows removal or rename of @@ -486,7 +487,7 @@ void phar_entry_remove(phar_entry_data *idata, char **error) /* {{{ */ /** * 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 @@ -506,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) ) { @@ -1256,9 +1257,11 @@ 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; + zend_string_init(alias, alias_len, mydata->is_persistent) : + 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; @@ -1270,7 +1273,7 @@ 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"); @@ -1315,7 +1318,7 @@ static zend_result phar_parse_pharfile(php_stream *fp, char *fname, size_t fname /** * Create or open a phar for writing */ -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_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; @@ -1345,7 +1348,7 @@ zend_result phar_open_or_create_filename(char *fname, size_t fname_len, char *al 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) { if (pphar) { *pphar = *test; } @@ -1380,15 +1383,15 @@ zend_result phar_open_or_create_filename(char *fname, size_t fname_len, char *al 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 ? ZSTR_VAL(alias) : NULL, alias ? ZSTR_LEN(alias) : 0, 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 ? ZSTR_VAL(alias) : NULL, alias ? ZSTR_LEN(alias) : 0, 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 ? ZSTR_VAL(alias) : NULL, alias ? ZSTR_LEN(alias) : 0, is_data, options, pphar, error); } /* }}} */ @@ -1515,8 +1518,7 @@ zend_result phar_create_or_parse_filename(char *fname, size_t fname_len, char *a } 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 ? zend_string_init(alias, alias_len, false) : zend_string_init(mydata->fname, fname_len, false); } if (alias_len && alias) { @@ -1548,7 +1550,7 @@ zend_result phar_create_or_parse_filename(char *fname, size_t fname_len, char *a * 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; @@ -1562,7 +1564,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; @@ -1590,7 +1592,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 ? ZSTR_VAL(alias) : NULL, alias ? ZSTR_LEN(alias) : 0, options, pphar, error); if (actual) { zend_string_release_ex(actual, 0); @@ -2322,7 +2324,7 @@ zend_result phar_split_fname(const char *filename, size_t filename_len, char **a * Invoked when a user calls Phar::mapPhar() from within an executing .phar * to set up its manifest directly */ -zend_result phar_open_executed_filename(char *alias, size_t alias_len, char **error) /* {{{ */ +zend_result phar_open_executed_filename(zend_string *alias, char **error) /* {{{ */ { if (error) { *error = NULL; @@ -2337,7 +2339,7 @@ zend_result phar_open_executed_filename(char *alias, size_t alias_len, char **er return FAILURE; } - if (phar_open_parsed_phar(ZSTR_VAL(fname), ZSTR_LEN(fname), alias, alias_len, 0, REPORT_ERRORS, NULL, 0) == SUCCESS) { + if (phar_open_parsed_phar(ZSTR_VAL(fname), ZSTR_LEN(fname), alias, 0, REPORT_ERRORS, NULL, 0) == SUCCESS) { return SUCCESS; } @@ -2370,7 +2372,7 @@ zend_result phar_open_executed_filename(char *alias, size_t alias_len, char **er 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 ? ZSTR_VAL(alias) : NULL, alias ? ZSTR_LEN(alias) : 0, REPORT_ERRORS, NULL, error); if (actual) { zend_string_release_ex(actual, 0); @@ -2544,7 +2546,7 @@ void phar_flush_ex(phar_archive_data *phar, zend_string *user_stub, bool is_defa phar_entry_info *entry, *newentry; size_t halt_offset; - int restore_alias_len, global_flags = 0; + int global_flags = 0; bool must_close_old_file = false; bool has_dirs = false; char manifest[18], entry_buffer[24]; @@ -2860,12 +2862,14 @@ void phar_flush_ex(phar_archive_data *phar, zend_string *user_stub, bool is_defa * 4: phar metadata length * ?: phar metadata */ - restore_alias_len = phar->alias_len; + size_t written_alias_len; if (phar->is_temporary_alias) { - phar->alias_len = 0; + written_alias_len = 0; + } else { + written_alias_len = ZSTR_LEN(phar->alias); // TODO: null 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') { @@ -2882,18 +2886,17 @@ void phar_flush_ex(phar_archive_data *phar, zend_string *user_stub, bool is_defa *(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 != 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; if (error) { spprintf(error, 0, "unable to write manifest header of new phar \"%s\"", phar->fname); @@ -2902,8 +2905,6 @@ void phar_flush_ex(phar_archive_data *phar, zend_string *user_stub, bool is_defa 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) && ZSTR_LEN(main_metadata_str.s) != php_stream_write(newfile, ZSTR_VAL(main_metadata_str.s), ZSTR_LEN(main_metadata_str.s)))) { @@ -2914,7 +2915,6 @@ void phar_flush_ex(phar_archive_data *phar, zend_string *user_stub, bool is_defa } php_stream_close(newfile); - phar->alias_len = restore_alias_len; if (error) { spprintf(error, 0, "unable to write manifest meta-data of new phar \"%s\"", phar->fname); @@ -3271,7 +3271,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; @@ -3456,7 +3456,8 @@ void phar_request_initialize(void) /* {{{ */ if (!PHAR_G(request_init)) { PHAR_G(last_phar) = NULL; - PHAR_G(last_phar_name) = PHAR_G(last_alias) = NULL; + PHAR_G(last_phar_name) = NULL; + PHAR_G(last_alias) = NULL; PHAR_G(has_bz2) = zend_hash_str_exists(&module_registry, "bz2", sizeof("bz2")-1); PHAR_G(has_zlib) = zend_hash_str_exists(&module_registry, "zlib", sizeof("zlib")-1); PHAR_G(request_init) = 1; diff --git a/ext/phar/phar_internal.h b/ext/phar/phar_internal.h index 740274a34e2d9..14de38f132149 100644 --- a/ext/phar/phar_internal.h +++ b/ext/phar/phar_internal.h @@ -150,8 +150,7 @@ ZEND_BEGIN_MODULE_GLOBALS(phar) /* phar_get_archive cache */ char* last_phar_name; uint32_t last_phar_name_len; - char* last_alias; - uint32_t last_alias_len; + zend_string*last_alias; phar_archive_data* last_phar; HashTable mime_types; ZEND_END_MODULE_GLOBALS(phar) @@ -248,8 +247,7 @@ struct _phar_archive_data { /* for phar_detect_fname_ext, this stores the location of the file extension within fname */ char *ext; uint32_t ext_len; - char *alias; - uint32_t alias_len; + zend_string *alias; char version[12]; size_t halt_offset; HashTable manifest; @@ -405,12 +403,12 @@ void phar_object_init(void); void phar_destroy_phar_data(phar_archive_data *phar); 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_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_result phar_open_from_filename(char *fname, size_t fname_len, zend_string *alias, uint32_t options, phar_archive_data** pphar, char **error); +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_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_result phar_open_executed_filename(char *alias, size_t alias_len, char **error); +zend_result phar_open_executed_filename(zend_string *alias, char **error); zend_result phar_free_alias(phar_archive_data *phar); -zend_result phar_get_archive(phar_archive_data **archive, char *fname, size_t fname_len, char *alias, size_t alias_len, char **error); +zend_result phar_get_archive(phar_archive_data **archive, 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, char *fname, char **signature, size_t *signature_len, char **error); zend_result phar_create_signature(phar_archive_data *phar, php_stream *fp, char **signature, size_t *signature_length, char **error); diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index 26bbfb634aa9e..6bda556323e4d 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -550,8 +550,9 @@ 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, *f404 = NULL, *ru = NULL; - size_t alias_len = 0, f404_len = 0, free_pathinfo = 0; + zend_string *alias = NULL; + char *error, *index_php = NULL, *f404 = NULL, *ru = NULL; + size_t f404_len = 0, free_pathinfo = 0; size_t ru_len = 0; char *fname, *path_info, *mime_type = NULL, *entry, *pt; const char *basename; @@ -562,13 +563,13 @@ PHP_METHOD(Phar, webPhar) phar_entry_info *info = NULL; size_t sapi_mod_name_len = strlen(sapi_module.name); - if (zend_parse_parameters(ZEND_NUM_ARGS(), "|s!s!s!af!", &alias, &alias_len, &index_php, &index_php_len, &f404, &f404_len, &mimeoverride, &rewrite_fci, &rewrite_fcc) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|S!s!s!af!", &alias, &index_php, &index_php_len, &f404, &f404_len, &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); @@ -761,7 +762,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, 0)) == NULL) { phar_do_404(phar, fname, fname_len, f404, f404_len, entry, entry_len); @@ -807,7 +808,7 @@ PHP_METHOD(Phar, webPhar) } } - 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, 0)) == NULL) { phar_do_404(phar, fname, fname_len, f404, f404_len, entry, entry_len); zend_bailout(); @@ -961,17 +962,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); @@ -982,16 +983,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; + zend_string *alias = NULL; + size_t fname_len; - 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); @@ -1114,8 +1116,9 @@ static const spl_other_handler phar_spl_foreign_handler = { */ PHP_METHOD(Phar, __construct) { - char *fname, *alias = NULL, *error, *arch = NULL, *entry = NULL, *save_fname; - size_t fname_len, alias_len = 0; + char *fname, *error, *arch = NULL, *entry = NULL, *save_fname; + zend_string *alias = NULL; + size_t fname_len; size_t arch_len, entry_len; bool is_data; zend_long flags = SPL_FILE_DIR_SKIPDOTS|SPL_FILE_DIR_UNIXPATHS; @@ -1129,11 +1132,11 @@ PHP_METHOD(Phar, __construct) is_data = instanceof_function(Z_OBJCE_P(zobj), 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(); } } @@ -1161,7 +1164,7 @@ PHP_METHOD(Phar, __construct) #endif } - 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 (fname == arch && fname != save_fname) { efree(arch); @@ -1306,7 +1309,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); @@ -1347,7 +1350,8 @@ PHP_METHOD(Phar, unlinkArchive) /* invalidate phar cache */ PHAR_G(last_phar) = NULL; - PHAR_G(last_phar_name) = PHAR_G(last_alias) = NULL; + PHAR_G(last_phar_name) = NULL; + PHAR_G(last_alias) = NULL; phar_archive_delref(phar); unlink(fname); @@ -2166,10 +2170,8 @@ 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); } @@ -2186,7 +2188,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; } } @@ -2246,7 +2247,8 @@ static zend_object *phar_convert_to_other(phar_archive_data *source, int convert /* invalidate phar cache */ PHAR_G(last_phar) = NULL; - PHAR_G(last_phar_name) = PHAR_G(last_alias) = NULL; + PHAR_G(last_phar_name) = NULL; + PHAR_G(last_alias) = NULL; phar = (phar_archive_data *) ecalloc(1, sizeof(phar_archive_data)); /* set whole-archive compression and type from parameter */ @@ -2675,8 +2677,12 @@ 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); + // TODO: what was the point of the fname != alias check? Adding a check for the byte contents make some cache_list tests fail... + if (phar_obj->archive->alias/* && !zend_string_equals_cstr(phar_obj->archive->alias, phar_obj->archive->fname, phar_obj->archive->fname_len)*/) { + 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); } } /* }}} */ @@ -2700,9 +2706,9 @@ PHP_METHOD(Phar, getPath) PHP_METHOD(Phar, setAlias) { zend_string *new_alias = NULL; - char *error, *oldalias; + char *error; + zend_string *oldalias; phar_archive_data *fd_ptr; - size_t oldalias_len; int old_temp, readd = 0; if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &new_alias) == FAILURE) { @@ -2719,7 +2725,8 @@ PHP_METHOD(Phar, setAlias) /* invalidate phar cache */ PHAR_G(last_phar) = NULL; - PHAR_G(last_phar_name) = PHAR_G(last_alias) = NULL; + PHAR_G(last_phar_name) = NULL; + PHAR_G(last_alias) = NULL; if (phar_obj->archive->is_data) { if (phar_obj->archive->is_tar) { @@ -2732,7 +2739,7 @@ PHP_METHOD(Phar, setAlias) RETURN_THROWS(); } - if (zend_string_equals_cstr(new_alias, phar_obj->archive->alias, phar_obj->archive->alias_len)) { + if (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))) { @@ -2755,18 +2762,21 @@ 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 && NULL != (fd_ptr = zend_hash_find_ptr(&(PHAR_G(phar_alias_map)), phar_obj->archive->alias))) { + zend_hash_del(&(PHAR_G(phar_alias_map)), phar_obj->archive->alias); readd = 1; } 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 = pestrndup(ZSTR_VAL(new_alias), ZSTR_LEN(new_alias), phar_obj->archive->is_persistent); + 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); + GC_MAKE_PERSISTENT_LOCAL(phar_obj->archive->alias); + } else { + phar_obj->archive->alias = zend_string_copy(new_alias); + } } else { phar_obj->archive->alias = NULL; } @@ -2776,11 +2786,10 @@ PHP_METHOD(Phar, setAlias) if (error) { 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(); @@ -2789,7 +2798,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(oldalias); } RETURN_TRUE; @@ -4478,7 +4487,7 @@ PHP_METHOD(PharFileInfo, __construct) RETURN_THROWS(); } - if (phar_open_from_filename(arch, arch_len, NULL, 0, REPORT_ERRORS, &phar_data, &error) == FAILURE) { + if (phar_open_from_filename(arch, arch_len, NULL, REPORT_ERRORS, &phar_data, &error) == FAILURE) { efree(arch); efree(entry); if (error) { diff --git a/ext/phar/stream.c b/ext/phar/stream.c index 0c4b12fd73d53..fad6a922a2cf8 100644 --- a/ext/phar/stream.c +++ b/ext/phar/stream.c @@ -116,7 +116,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)) { @@ -139,7 +139,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)) { @@ -235,7 +235,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); @@ -580,7 +580,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, &error)) { + if (FAILURE == phar_get_archive(&phar, ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), NULL, &error)) { php_url_free(resource); if (error) { efree(error); @@ -746,7 +746,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); @@ -763,7 +763,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); } @@ -812,7 +812,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 157cb4bac647d..659607b8a3894 100644 --- a/ext/phar/tar.c +++ b/ext/phar/tar.c @@ -204,7 +204,8 @@ static zend_result phar_tar_process_metadata(phar_entry_info *entry, php_stream zend_result phar_parse_tarfile(php_stream* fp, char *fname, size_t fname_len, char *alias, size_t alias_len, phar_archive_data** pphar, uint32_t compression, char **error) /* {{{ */ { - char buf[512], *actual_alias = NULL, *p; + char buf[512], *p; + zend_string *actual_alias = NULL; phar_entry_info entry = {0}; size_t pos = 0, read, totalsize; tar_header *hdr; @@ -567,9 +568,11 @@ zend_result phar_parse_tarfile(php_stream* fp, char *fname, size_t fname_len, ch return FAILURE; } - actual_alias = pestrndup(buf, size, myphar->is_persistent); + actual_alias = zend_string_init(buf, size, myphar->is_persistent); + if (myphar->is_persistent) { + GC_MAKE_PERSISTENT_LOCAL(actual_alias); + } myphar->alias = actual_alias; - myphar->alias_len = size; php_stream_seek(fp, pos, SEEK_SET); } else { if (error) { @@ -667,7 +670,7 @@ zend_result phar_parse_tarfile(php_stream* fp, char *fname, size_t fname_len, ch 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); @@ -677,7 +680,7 @@ zend_result phar_parse_tarfile(php_stream* fp, char *fname, size_t fname_len, ch } } - zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), actual_alias, myphar->alias_len, myphar); + zend_hash_add_ptr(&(PHAR_G(phar_alias_map)), actual_alias, myphar); } else { phar_archive_data *fd_ptr; @@ -691,12 +694,14 @@ zend_result phar_parse_tarfile(php_stream* fp, char *fname, size_t fname_len, ch 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(alias, alias_len, 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; @@ -999,13 +1004,13 @@ void phar_tar_flush(phar_archive_data *phar, zend_string *user_stub, bool is_def } /* 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) { spprintf(error, 0, "phar error: unable to create temporary file"); return; } - 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))) { if (error) { spprintf(error, 0, "unable to set alias in tar-based phar \"%s\"", phar->fname); } @@ -1013,7 +1018,7 @@ void phar_tar_flush(phar_archive_data *phar, zend_string *user_stub, bool is_def return; } - 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 f3310caa033e2..9c29b4f887116 100644 --- a/ext/phar/util.c +++ b/ext/phar/util.c @@ -310,7 +310,7 @@ zend_string *phar_find_in_include_path(zend_string *filename, phar_archive_data if (*ZSTR_VAL(filename) == '.') { size_t try_len; - if (FAILURE == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL)) { + if (FAILURE == phar_get_archive(&phar, arch, arch_len, NULL, NULL)) { efree(arch); return NULL; } @@ -491,7 +491,7 @@ zend_result phar_get_entry_data(phar_entry_data **ret, char *fname, size_t fname *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; } @@ -646,7 +646,7 @@ phar_entry_data *phar_get_or_create_entry_data(char *fname, size_t fname_len, ch 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; } @@ -980,7 +980,8 @@ zend_result phar_free_alias(phar_archive_data *phar) /* {{{ */ /* invalidate phar cache */ PHAR_G(last_phar) = NULL; - PHAR_G(last_phar_name) = PHAR_G(last_alias) = NULL; + PHAR_G(last_phar_name) = NULL; + PHAR_G(last_alias) = NULL; return SUCCESS; } @@ -990,7 +991,7 @@ zend_result phar_free_alias(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, char *fname, size_t fname_len, char *alias, size_t alias_len, char **error) /* {{{ */ +zend_result phar_get_archive(phar_archive_data **archive, char *fname, size_t fname_len, zend_string *alias, char **error) /* {{{ */ { phar_archive_data *fd, *fd_ptr; char *my_realpath, *save; @@ -1006,40 +1007,39 @@ zend_result phar_get_archive(phar_archive_data **archive, char *fname, size_t fn 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 && NULL != (fd_ptr = zend_hash_find_ptr(&(PHAR_G(phar_alias_map)), 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) && 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) { @@ -1056,12 +1056,11 @@ zend_result phar_get_archive(phar_archive_data **archive, char *fname, size_t fn 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; } } @@ -1075,26 +1074,25 @@ zend_result phar_get_archive(phar_archive_data **archive, char *fname, size_t fn *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 && NULL != (fd_ptr = zend_hash_find_ptr(&(PHAR_G(phar_alias_map)), 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; } @@ -1105,10 +1103,10 @@ zend_result phar_get_archive(phar_archive_data **archive, char *fname, size_t fn /* 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; } @@ -1118,7 +1116,6 @@ zend_result phar_get_archive(phar_archive_data **archive, char *fname, size_t fn 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; } @@ -1130,7 +1127,6 @@ zend_result phar_get_archive(phar_archive_data **archive, char *fname, size_t fn 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; } @@ -1142,7 +1138,6 @@ zend_result phar_get_archive(phar_archive_data **archive, char *fname, size_t fn 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; } @@ -1165,8 +1160,8 @@ zend_result phar_get_archive(phar_archive_data **archive, char *fname, size_t fn *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); @@ -1175,7 +1170,6 @@ zend_result phar_get_archive(phar_archive_data **archive, char *fname, size_t fn 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; } @@ -2077,7 +2071,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); + phar->alias = zend_string_copy(phar->alias); } if (phar->signature) { @@ -2121,9 +2115,10 @@ zend_result phar_copy_on_write(phar_archive_data **pphar) /* {{{ */ newpphar = Z_PTR_P(pzv); /* invalidate phar cache */ PHAR_G(last_phar) = NULL; - PHAR_G(last_phar_name) = PHAR_G(last_alias) = NULL; + PHAR_G(last_phar_name) = NULL; + PHAR_G(last_alias) = 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 f1587594675f2..4fc78a1994352 100644 --- a/ext/phar/zip.c +++ b/ext/phar/zip.c @@ -234,7 +234,8 @@ int phar_parse_zipfile(php_stream *fp, char *fname, size_t fname_len, char *alia uint16_t i; phar_archive_data *mydata = NULL; phar_entry_info entry = {0}; - char *p = buf, *ext, *actual_alias = NULL; + char *p = buf, *ext; + zend_string *actual_alias = NULL; char *metadata = NULL; size = php_stream_tell(fp); @@ -649,7 +650,6 @@ int phar_parse_zipfile(php_stream *fp, char *fname, size_t fname_len, char *alia fp->readpos = 0; /* the above lines should be for php < 5.2.6 after 5.3 filters are fixed */ - 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)); @@ -660,19 +660,8 @@ int phar_parse_zipfile(php_stream *fp, char *fname, size_t fname_len, char *alia 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 || !actual_alias) { zend_string_release_ex(entry.filename, entry.is_persistent); @@ -692,19 +681,8 @@ int phar_parse_zipfile(php_stream *fp, char *fname, size_t fname_len, char *alia 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 || !actual_alias) { zend_string_release_ex(entry.filename, entry.is_persistent); @@ -714,19 +692,8 @@ int phar_parse_zipfile(php_stream *fp, char *fname, size_t fname_len, char *alia 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 || !actual_alias) { zend_string_release_ex(entry.filename, entry.is_persistent); @@ -760,35 +727,36 @@ int phar_parse_zipfile(php_stream *fp, char *fname, size_t fname_len, char *alia 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_efree(actual_alias); 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_efree(actual_alias); 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 = entry.is_persistent ? zend_string_init(ZSTR_VAL(actual_alias), ZSTR_LEN(actual_alias), false) : actual_alias; if (entry.is_persistent) { - efree(actual_alias); + GC_MAKE_PERSISTENT_LOCAL(mydata->alias); + zend_string_efree(actual_alias); } - zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), mydata->alias, mydata->alias_len, mydata); + zend_hash_add_ptr(&(PHAR_G(phar_alias_map)), mydata->alias, mydata); } else { phar_archive_data *fd_ptr; @@ -803,12 +771,13 @@ int phar_parse_zipfile(php_stream *fp, char *fname, size_t fname_len, char *alia } } - 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(alias, alias_len, 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; @@ -1286,20 +1255,20 @@ void phar_zip_flush(phar_archive_data *phar, zend_string *user_stub, bool is_def } /* 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) { spprintf(error, 0, "phar error: unable to create temporary file"); return; } - 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))) { if (error) { spprintf(error, 0, "unable to set alias in zip-based phar \"%s\"", phar->fname); } return; } - 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)); @@ -1308,8 +1277,8 @@ void phar_zip_flush(phar_archive_data *phar, zend_string *user_stub, bool is_def } /* 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; } }