1
0
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:
Greg Beaver
2008-02-11 06:46:44 +00:00
parent 3874e12ee5
commit 78e8eb3900
5 changed files with 76 additions and 26 deletions
+8 -7
View File
@@ -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;
}
+2 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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) {