mirror of
https://github.com/php/php-src.git
synced 2026-04-28 18:53:33 +02:00
major refactoring of internal handling of aliases.
1) rename is_explicit_alias to is_temporary_alias for clarity and flip the value 2) fix setAlias so that it sets a permanent to-be-saved alias, and restores the old one on error 3) fix Phar constructor to work with sub-directories in RecursiveDirectoryIterator
This commit is contained in:
+8
-7
@@ -498,7 +498,7 @@ int phar_open_file(php_stream *fp, char *fname, int fname_len, char *alias, int
|
||||
php_uint32 manifest_len, manifest_count, manifest_flags, manifest_index, tmp_len, sig_flags;
|
||||
php_uint16 manifest_ver;
|
||||
long offset;
|
||||
int register_alias, sig_len;
|
||||
int register_alias, sig_len, temp_alias = 0;
|
||||
char *signature = NULL;
|
||||
|
||||
if (pphar) {
|
||||
@@ -808,8 +808,9 @@ int phar_open_file(php_stream *fp, char *fname, int fname_len, char *alias, int
|
||||
alias = NULL;
|
||||
alias_len = 0;
|
||||
register_alias = 0;
|
||||
} else {
|
||||
} else if (alias_len) {
|
||||
register_alias = 1;
|
||||
temp_alias = 1;
|
||||
}
|
||||
|
||||
/* we have 5 32-bit items plus 1 byte at least */
|
||||
@@ -929,10 +930,10 @@ int phar_open_file(php_stream *fp, char *fname, int fname_len, char *alias, int
|
||||
phar_request_initialize(TSRMLS_C);
|
||||
zend_hash_add(&(PHAR_GLOBALS->phar_fname_map), mydata->fname, fname_len, (void*)&mydata, sizeof(phar_archive_data*), NULL);
|
||||
if (register_alias) {
|
||||
mydata->is_explicit_alias = 1;
|
||||
mydata->is_temporary_alias = temp_alias;
|
||||
zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, (void*)&mydata, sizeof(phar_archive_data*), NULL);
|
||||
} else {
|
||||
mydata->is_explicit_alias = 0;
|
||||
mydata->is_temporary_alias = 1;
|
||||
}
|
||||
efree(savebuf);
|
||||
|
||||
@@ -1069,7 +1070,7 @@ int phar_create_or_parse_filename(char *fname, int fname_len, char *alias, int a
|
||||
mydata->alias = alias ? estrndup(alias, alias_len) : estrndup(mydata->fname, fname_len);
|
||||
mydata->alias_len = alias ? alias_len : fname_len;
|
||||
snprintf(mydata->version, sizeof(mydata->version), "%s", PHAR_API_VERSION_STR);
|
||||
mydata->is_explicit_alias = alias ? 1 : 0;
|
||||
mydata->is_temporary_alias = alias ? 0 : 1;
|
||||
mydata->internal_file_start = -1;
|
||||
mydata->fp = fp;
|
||||
mydata->is_writeable = 1;
|
||||
@@ -1201,7 +1202,7 @@ static int phar_open_fp(php_stream* fp, char *fname, int fname_len, char *alias,
|
||||
array_init(&filterparams);
|
||||
/* ext/zlib zval_dtors a separated zval, so we have to make sure it doesn't destroy ours */
|
||||
#if PHP_VERSION_ID < 50300
|
||||
filterparams->refcount = 26;
|
||||
filterparams.refcount = 26;
|
||||
#else
|
||||
Z_SET_REFCOUNT(filterparams, 26);
|
||||
#endif
|
||||
@@ -2082,7 +2083,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, long len, char **error
|
||||
* ?: phar metadata
|
||||
*/
|
||||
restore_alias_len = phar->alias_len;
|
||||
if (!phar->is_explicit_alias) {
|
||||
if (phar->is_temporary_alias) {
|
||||
phar->alias_len = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -265,7 +265,8 @@ struct _phar_archive_data {
|
||||
int sig_len;
|
||||
char *signature;
|
||||
zval *metadata;
|
||||
int is_explicit_alias:1;
|
||||
/* if 1, then this alias was manually specified by the user and is not a permanent alias */
|
||||
int is_temporary_alias:1;
|
||||
int is_modified:1;
|
||||
int is_writeable:1;
|
||||
int is_brandnew:1;
|
||||
|
||||
+43
-9
@@ -1046,8 +1046,8 @@ PHP_METHOD(Phar, __construct)
|
||||
#if !HAVE_SPL
|
||||
zend_throw_exception_ex(zend_exception_get_default(TSRMLS_C), 0 TSRMLS_CC, "Cannot instantiate Phar object without SPL extension");
|
||||
#else
|
||||
char *fname, *alias = NULL, *error;
|
||||
int fname_len, alias_len = 0;
|
||||
char *fname, *alias = NULL, *error, *arch, *entry = NULL, *save_fname;
|
||||
int fname_len, alias_len = 0, arch_len, entry_len;
|
||||
long flags = 0;
|
||||
phar_archive_object *phar_obj;
|
||||
phar_archive_data *phar_data;
|
||||
@@ -1064,23 +1064,45 @@ PHP_METHOD(Phar, __construct)
|
||||
return;
|
||||
}
|
||||
|
||||
if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len)) {
|
||||
/* use arch for fname instead of fname */
|
||||
/* this allows support for RecursiveDirectoryIterator of subdirectories */
|
||||
save_fname = fname;
|
||||
fname = arch;
|
||||
fname_len = arch_len;
|
||||
}
|
||||
if (phar_open_or_create_filename(fname, fname_len, alias, alias_len, REPORT_ERRORS, &phar_data, &error TSRMLS_CC) == FAILURE) {
|
||||
if (fname == arch) {
|
||||
efree(arch);
|
||||
fname = save_fname;
|
||||
}
|
||||
if (error) {
|
||||
efree(entry);
|
||||
zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
|
||||
"Cannot open phar file '%s' with alias '%s': %s", fname, alias, error);
|
||||
efree(error);
|
||||
} else {
|
||||
efree(entry);
|
||||
zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
|
||||
"Cannot open phar file '%s' with alias '%s'", fname, alias);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (fname == arch) {
|
||||
efree(arch);
|
||||
fname = save_fname;
|
||||
}
|
||||
phar_data->refcount++;
|
||||
phar_obj->arc.archive = phar_data;
|
||||
phar_obj->spl.oth_handler = &phar_spl_foreign_handler;
|
||||
|
||||
fname_len = spprintf(&fname, 0, "phar://%s", phar_data->fname);
|
||||
if (entry) {
|
||||
fname_len = spprintf(&fname, 0, "phar://%s%s", phar_data->fname, entry);
|
||||
efree(entry);
|
||||
} else {
|
||||
fname_len = spprintf(&fname, 0, "phar://%s", phar_data->fname);
|
||||
}
|
||||
INIT_PZVAL(&arg1);
|
||||
ZVAL_STRINGL(&arg1, fname, fname_len, 0);
|
||||
|
||||
@@ -1976,9 +1998,9 @@ PHP_METHOD(Phar, getAlias)
|
||||
*/
|
||||
PHP_METHOD(Phar, setAlias)
|
||||
{
|
||||
char *alias, *error;
|
||||
char *alias, *error, *oldalias;
|
||||
phar_archive_data **fd_ptr;
|
||||
int alias_len;
|
||||
int alias_len, oldalias_len, old_temp, readd = 0;
|
||||
PHAR_ARCHIVE_OBJECT();
|
||||
|
||||
if (PHAR_G(readonly)) {
|
||||
@@ -1999,23 +2021,35 @@ PHP_METHOD(Phar, setAlias)
|
||||
}
|
||||
if (phar_obj->arc.archive->alias_len && SUCCESS == zend_hash_find(&(PHAR_GLOBALS->phar_alias_map), phar_obj->arc.archive->alias, phar_obj->arc.archive->alias_len, (void**)&fd_ptr)) {
|
||||
zend_hash_del(&(PHAR_GLOBALS->phar_alias_map), phar_obj->arc.archive->alias, phar_obj->arc.archive->alias_len);
|
||||
readd = 1;
|
||||
}
|
||||
|
||||
if (phar_obj->arc.archive->alias) {
|
||||
efree(phar_obj->arc.archive->alias);
|
||||
}
|
||||
oldalias = phar_obj->arc.archive->alias;
|
||||
oldalias_len = phar_obj->arc.archive->alias_len;
|
||||
old_temp = phar_obj->arc.archive->is_temporary_alias;
|
||||
if (alias_len) {
|
||||
phar_obj->arc.archive->alias = estrndup(alias, alias_len);
|
||||
} else {
|
||||
phar_obj->arc.archive->alias = NULL;
|
||||
}
|
||||
phar_obj->arc.archive->alias_len = alias_len;
|
||||
phar_obj->arc.archive->is_explicit_alias = 1;
|
||||
phar_obj->arc.archive->is_temporary_alias = 0;
|
||||
|
||||
phar_flush(phar_obj->arc.archive, NULL, 0, &error TSRMLS_CC);
|
||||
if (error) {
|
||||
phar_obj->arc.archive->alias = oldalias;
|
||||
phar_obj->arc.archive->alias_len = oldalias_len;
|
||||
phar_obj->arc.archive->is_temporary_alias = old_temp;
|
||||
zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, error);
|
||||
if (readd) {
|
||||
zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), oldalias, oldalias_len, (void*)&(phar_obj->arc.archive), sizeof(phar_archive_data*), NULL);
|
||||
}
|
||||
efree(error);
|
||||
return;
|
||||
}
|
||||
zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, (void*)&(phar_obj->arc.archive), sizeof(phar_archive_data*), NULL);
|
||||
if (oldalias) {
|
||||
efree(oldalias);
|
||||
}
|
||||
RETURN_TRUE;
|
||||
}
|
||||
|
||||
+17
-5
@@ -312,12 +312,12 @@ int phar_open_tarfile(php_stream* fp, char *fname, int fname_len, char *alias, i
|
||||
}
|
||||
myphar = *actual;
|
||||
if (actual_alias) {
|
||||
myphar->is_explicit_alias = 1;
|
||||
myphar->is_temporary_alias = 0;
|
||||
zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), actual_alias, myphar->alias_len, (void*)&myphar, sizeof(phar_archive_data*), NULL);
|
||||
} else {
|
||||
myphar->alias = estrndup(myphar->fname, fname_len);
|
||||
myphar->alias_len = fname_len;
|
||||
myphar->is_explicit_alias = 0;
|
||||
myphar->is_temporary_alias = 1;
|
||||
}
|
||||
if (pphar) {
|
||||
*pphar = myphar;
|
||||
@@ -448,14 +448,26 @@ int phar_tar_flush(phar_archive_data *phar, char *user_stub, long len, char **er
|
||||
entry.phar = phar;
|
||||
entry.fp_type = PHAR_MOD;
|
||||
/* set alias */
|
||||
if (phar->is_explicit_alias) {
|
||||
if (!phar->is_temporary_alias && phar->alias_len) {
|
||||
entry.filename = estrndup(".phar/alias.txt", sizeof(".phar/alias.txt")-1);
|
||||
entry.filename_len = sizeof(".phar/alias.txt")-1;
|
||||
entry.fp = php_stream_fopen_tmpfile();
|
||||
entry.crc32 = phar_tar_checksum(phar->alias, phar->alias_len);
|
||||
php_stream_write(entry.fp, phar->alias, phar->alias_len);
|
||||
if (phar->alias_len != (int)php_stream_write(entry.fp, phar->alias, phar->alias_len)) {
|
||||
if (error) {
|
||||
spprintf(error, 0, "unable to set alias in tar-based phar \"%s\"", phar->fname);
|
||||
}
|
||||
return EOF;
|
||||
}
|
||||
entry.uncompressed_filesize = phar->alias_len;
|
||||
zend_hash_update(&phar->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info), NULL);
|
||||
if (SUCCESS != zend_hash_update(&phar->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info), NULL)) {
|
||||
if (error) {
|
||||
spprintf(error, 0, "unable to set alias in tar-based phar \"%s\"", phar->fname);
|
||||
}
|
||||
return EOF;
|
||||
}
|
||||
} else {
|
||||
zend_hash_del(&phar->manifest, ".phar/alias.txt", sizeof(".phar/alias.txt")-1);
|
||||
}
|
||||
|
||||
/* set stub */
|
||||
|
||||
+6
-4
@@ -350,7 +350,7 @@ foundit:
|
||||
}
|
||||
}
|
||||
|
||||
mydata->is_explicit_alias = 1;
|
||||
mydata->is_temporary_alias = 0;
|
||||
mydata->alias_len = zipentry.uncompsize;
|
||||
zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), mydata->alias, mydata->alias_len, (void*)&mydata, sizeof(phar_archive_data*), NULL);
|
||||
/* return to central directory parsing */
|
||||
@@ -659,11 +659,11 @@ int phar_zip_flush(phar_archive_data *phar, char *user_stub, long len, char **er
|
||||
entry.fp_type = PHAR_MOD;
|
||||
|
||||
/* set alias */
|
||||
if (phar->is_explicit_alias) {
|
||||
if (!phar->is_temporary_alias && phar->alias_len) {
|
||||
entry.fp = php_stream_fopen_tmpfile();
|
||||
if (phar->alias_len != (int)php_stream_write(entry.fp, phar->alias, phar->alias_len)) {
|
||||
if (error) {
|
||||
spprintf(error, 0, "unable to set alias in new zip-based phar \"%s\"", phar->fname);
|
||||
spprintf(error, 0, "unable to set alias in zip-based phar \"%s\"", phar->fname);
|
||||
}
|
||||
return EOF;
|
||||
}
|
||||
@@ -673,10 +673,12 @@ int phar_zip_flush(phar_archive_data *phar, char *user_stub, long len, char **er
|
||||
entry.is_modified = 1;
|
||||
if (SUCCESS != zend_hash_update(&phar->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info), NULL)) {
|
||||
if (error) {
|
||||
spprintf(error, 0, "unable to set alias in new zip-based phar \"%s\"", phar->fname);
|
||||
spprintf(error, 0, "unable to set alias in zip-based phar \"%s\"", phar->fname);
|
||||
}
|
||||
return EOF;
|
||||
}
|
||||
} else {
|
||||
zend_hash_del(&phar->manifest, ".phar/alias.txt", sizeof(".phar/alias.txt")-1);
|
||||
}
|
||||
/* register alias */
|
||||
if (phar->alias_len) {
|
||||
|
||||
Reference in New Issue
Block a user