diff --git a/ext/phar/phar.c b/ext/phar/phar.c index b4cdd1577dd0..ee12c5b91feb 100644 --- a/ext/phar/phar.c +++ b/ext/phar/phar.c @@ -484,8 +484,15 @@ 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, const 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, + /* copyable & hash update */ zend_string *alias, + bool is_data, + uint32_t options, + phar_archive_data** pphar, + char **error +) { #ifdef PHP_WIN32 char *save_fname; ALLOCA_FLAG(fname_use_heap) @@ -503,7 +510,9 @@ static zend_result phar_open_parsed_phar(char *fname, size_t fname_len, const ch phar_unixify_path_separators(fname, fname_len); } #endif - phar_archive_data *phar = phar_get_archive(fname, fname_len, alias, alias_len, error); + const char *alias_cstr = alias ? ZSTR_VAL(alias) : NULL; + size_t alias_len = alias ? ZSTR_LEN(alias) : 0; + phar_archive_data *phar = phar_get_archive(fname, fname_len, alias_cstr, alias_len, error); /* logic is as follows: - If no alias was passed in, then it can match either and be valid - If an explicit alias was requested, ensure the filename passed in matches the phar's filename. @@ -552,7 +561,6 @@ static zend_result phar_open_parsed_phar(char *fname, size_t fname_len, const ch return FAILURE; } } -/* }}}*/ /** * Attempt to serialize the data. @@ -1333,10 +1341,8 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 5, 6) zend_result phar_open_or_create_filename( } return FAILURE; } -check_file:; - const char *alias_cstr = alias ? ZSTR_VAL(alias) : NULL; - size_t alias_len = alias ? ZSTR_LEN(alias) : 0; - if (phar_open_parsed_phar(ZSTR_VAL(fname), ZSTR_LEN(fname), alias_cstr, alias_len, is_data, options, test, &my_error) == SUCCESS) { +check_file: + if (phar_open_parsed_phar(ZSTR_VAL(fname), ZSTR_LEN(fname), alias, is_data, options, test, &my_error) == SUCCESS) { *pphar = *test; if ((*test)->is_data && !(*test)->is_tar && !(*test)->is_zip) { @@ -1538,9 +1544,7 @@ zend_result phar_open_from_filename( is_data = true; } - const char *alias_cstr = alias ? ZSTR_VAL(alias) : NULL; - size_t alias_len = alias ? ZSTR_LEN(alias) : 0; - if (phar_open_parsed_phar(fname, fname_len, alias_cstr, 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; @@ -2278,7 +2282,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(2) zend_result phar_open_executed_filename(/* copyable & hash update */ zend_string *alias, char **error) /* {{{ */ +ZEND_ATTRIBUTE_NONNULL_ARGS(2) zend_result phar_open_executed_filename(/* copyable & hash update */ zend_string *alias, char **error) /* {{{ */ { *error = NULL; @@ -2289,9 +2293,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(2) zend_result phar_open_executed_filename(/* copyab return FAILURE; } - const char *alias_cstr = alias ? ZSTR_VAL(alias) : NULL; - size_t alias_len = alias ? ZSTR_LEN(alias) : 0; - if (phar_open_parsed_phar(ZSTR_VAL(fname), ZSTR_LEN(fname), alias_cstr, 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; } diff --git a/ext/phar/util.c b/ext/phar/util.c index c1e752a8e6b2..2ab20bbd28ec 100644 --- a/ext/phar/util.c +++ b/ext/phar/util.c @@ -2008,14 +2008,13 @@ static void phar_manifest_copy_ctor(zval *zv) /* {{{ */ } /* }}} */ -static void phar_copy_cached_phar(phar_archive_data **pphar) /* {{{ */ +static phar_archive_data* phar_copy_cached_phar(const phar_archive_data *persistent_phar) /* {{{ */ { - phar_archive_data *phar; HashTable newmanifest; phar_archive_object *objphar; - phar = (phar_archive_data *) emalloc(sizeof(phar_archive_data)); - *phar = **pphar; + phar_archive_data *phar = emalloc(sizeof(phar_archive_data)); + *phar = *persistent_phar; phar->is_persistent = 0; zend_string_addref(phar->fname); @@ -2029,17 +2028,13 @@ static void phar_copy_cached_phar(phar_archive_data **pphar) /* {{{ */ phar_metadata_tracker_clone(&phar->metadata_tracker); - zend_hash_init(&newmanifest, sizeof(phar_entry_info), - zend_get_hash_value, destroy_phar_manifest_entry, 0); - zend_hash_copy(&newmanifest, &(*pphar)->manifest, phar_manifest_copy_ctor); + zend_hash_init(&newmanifest, sizeof(phar_entry_info), NULL, destroy_phar_manifest_entry, 0); + zend_hash_copy(&newmanifest, &persistent_phar->manifest, phar_manifest_copy_ctor); zend_hash_apply_with_argument(&newmanifest, phar_update_cached_entry, (void *)phar); phar->manifest = newmanifest; - zend_hash_init(&phar->mounted_dirs, sizeof(char *), - zend_get_hash_value, NULL, 0); - zend_hash_init(&phar->virtual_dirs, sizeof(char *), - zend_get_hash_value, NULL, 0); - zend_hash_copy(&phar->virtual_dirs, &(*pphar)->virtual_dirs, NULL); - *pphar = phar; + zend_hash_init(&phar->mounted_dirs, sizeof(char *), NULL, NULL, 0); + zend_hash_init(&phar->virtual_dirs, sizeof(char *), NULL, NULL, 0); + zend_hash_copy(&phar->virtual_dirs, &persistent_phar->virtual_dirs, NULL); /* now, scan the list of persistent Phar objects referencing this phar and update the pointers */ ZEND_HASH_MAP_FOREACH_PTR(&PHAR_G(phar_persist_map), objphar) { @@ -2047,29 +2042,26 @@ static void phar_copy_cached_phar(phar_archive_data **pphar) /* {{{ */ objphar->archive = phar; } } ZEND_HASH_FOREACH_END(); + return phar; } /* }}} */ zend_result phar_copy_on_write(phar_archive_data **pphar) /* {{{ */ { - zval zv, *pzv; - phar_archive_data *newpphar; + phar_archive_data *newpphar = phar_copy_cached_phar(*pphar); - ZVAL_PTR(&zv, *pphar); - pzv = zend_hash_add(&(PHAR_G(phar_fname_map)), (*pphar)->fname, &zv); + zval *pzv = zend_hash_add_ptr(&(PHAR_G(phar_fname_map)), newpphar->fname, newpphar); if (!pzv) { return FAILURE; } - phar_copy_cached_phar((phar_archive_data **)&Z_PTR_P(pzv)); - newpphar = Z_PTR_P(pzv); /* invalidate phar cache */ PHAR_G(last_phar) = NULL; 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)) { - zend_hash_del(&(PHAR_G(phar_fname_map)), (*pphar)->fname); + zend_hash_del(&(PHAR_G(phar_fname_map)), newpphar->fname); return FAILURE; }