Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 17 additions & 15 deletions ext/phar/phar.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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.
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand All @@ -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;
}

Expand Down
32 changes: 12 additions & 20 deletions ext/phar/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -2029,47 +2028,40 @@ 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) {
if (zend_string_equals(objphar->archive->fname, phar->fname)) {
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;
}

Expand Down