mirror of
https://github.com/php/php-src.git
synced 2025-08-18 06:58:55 +02:00
- MFB major fixes
* found felipe's segfault in util.c and fixed the segfault (3 tests fail due to odd behavior of . and .. on this machine) * fixed serious flaws in the setting/resetting of is_data - now it works properly. Assume all new PharData are tar-based, and allow passing Phar::ZIP to PharData constructor to override this * fix broken earlier commit, introduced segfault that broke 20 tests here
This commit is contained in:
parent
7efb792fe8
commit
76a9ec377b
5 changed files with 65 additions and 16 deletions
|
@ -406,7 +406,6 @@ int phar_open_loaded(char *fname, int fname_len, char *alias, int alias_len, int
|
|||
}
|
||||
}
|
||||
}
|
||||
phar->is_data = is_data && (phar->is_tar || phar->is_zip);
|
||||
if (pphar) {
|
||||
*pphar = phar;
|
||||
}
|
||||
|
@ -1033,12 +1032,12 @@ check_file:
|
|||
}
|
||||
|
||||
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
|
||||
/* assume zip-based phar */
|
||||
return phar_open_or_create_zip(fname, fname_len, alias, alias_len, is_data, options, pphar, error TSRMLS_CC);
|
||||
}
|
||||
|
||||
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
|
||||
/* assume tar-based phar */
|
||||
return phar_open_or_create_tar(fname, fname_len, alias, alias_len, is_data, options, pphar, error TSRMLS_CC);
|
||||
}
|
||||
|
||||
|
@ -1140,6 +1139,9 @@ int phar_create_or_parse_filename(char *fname, int fname_len, char *alias, int a
|
|||
if (is_data) {
|
||||
alias = NULL;
|
||||
alias_len = 0;
|
||||
mydata->is_data = 1;
|
||||
/* assume tar format, PharData can specify other */
|
||||
mydata->is_tar = 1;
|
||||
} else {
|
||||
phar_archive_data **fd_ptr;
|
||||
|
||||
|
|
|
@ -1120,7 +1120,7 @@ static spl_other_handler phar_spl_foreign_handler = {
|
|||
|
||||
/* {{{ proto void Phar::__construct(string fname [, int flags [, string alias]])
|
||||
* Construct a Phar archive object
|
||||
* {{{ proto void PharData::__construct(string fname [, int flags [, string alias]])
|
||||
* {{{ proto void PharData::__construct(string fname [[, int flags [, string alias]], int file format = Phar::TAR])
|
||||
* Construct a PharData archive object
|
||||
*/
|
||||
PHP_METHOD(Phar, __construct)
|
||||
|
@ -1130,22 +1130,13 @@ PHP_METHOD(Phar, __construct)
|
|||
#else
|
||||
char *fname, *alias = NULL, *error, *arch = NULL, *entry = NULL, *save_fname, *objname;
|
||||
int fname_len, alias_len = 0, arch_len, entry_len, is_data;
|
||||
long flags = 0;
|
||||
long flags = 0, format = 0;
|
||||
phar_archive_object *phar_obj;
|
||||
phar_archive_data *phar_data;
|
||||
zval *zobj = getThis(), arg1, arg2;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ls!", &fname, &fname_len, &flags, &alias, &alias_len) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
phar_obj = (phar_archive_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||
|
||||
if (phar_obj->arc.archive) {
|
||||
zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Cannot call constructor twice");
|
||||
return;
|
||||
}
|
||||
|
||||
PHAR_STR(phar_obj->std.ce->name, objname);
|
||||
|
||||
if (!strncmp(objname, "PharData", 8)) {
|
||||
|
@ -1154,6 +1145,21 @@ PHP_METHOD(Phar, __construct)
|
|||
is_data = 0;
|
||||
}
|
||||
|
||||
if (is_data) {
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ls!l", &fname, &fname_len, &flags, &alias, &alias_len, &format) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ls!", &fname, &fname_len, &flags, &alias, &alias_len) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (phar_obj->arc.archive) {
|
||||
zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Cannot call constructor twice");
|
||||
return;
|
||||
}
|
||||
|
||||
if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, !is_data, 2 TSRMLS_CC)) {
|
||||
/* use arch (the basename for the archive) for fname instead of fname */
|
||||
/* this allows support for RecursiveDirectoryIterator of subdirectories */
|
||||
|
@ -1193,11 +1199,28 @@ PHP_METHOD(Phar, __construct)
|
|||
return;
|
||||
}
|
||||
|
||||
if (is_data && phar_data->is_tar && phar_data->is_brandnew && format == PHAR_FORMAT_ZIP) {
|
||||
phar_data->is_zip = 1;
|
||||
phar_data->is_tar = 0;
|
||||
}
|
||||
|
||||
if (fname == arch) {
|
||||
efree(arch);
|
||||
fname = save_fname;
|
||||
}
|
||||
|
||||
if ((is_data && !phar_data->is_data) || (!is_data && phar_data->is_data)) {
|
||||
if (is_data) {
|
||||
zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
|
||||
"PharData class can only be used for non-executable tar and zip archives");
|
||||
} else {
|
||||
zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
|
||||
"Phar class can only be used for executable tar and zip archives");
|
||||
}
|
||||
efree(entry);
|
||||
return;
|
||||
}
|
||||
|
||||
is_data = phar_data->is_data;
|
||||
++(phar_data->refcount);
|
||||
phar_obj->arc.archive = phar_data;
|
||||
|
@ -1844,7 +1867,7 @@ static zval *phar_rename_archive(phar_archive_data *phar, char *ext, zend_bool c
|
|||
char *error;
|
||||
const char *pcr_error;
|
||||
int ext_len = ext ? strlen(ext) : 0;
|
||||
phar_archive_data **pphar;
|
||||
phar_archive_data **pphar = NULL;
|
||||
|
||||
if (!ext) {
|
||||
if (phar->is_zip) {
|
||||
|
@ -1912,6 +1935,7 @@ static zval *phar_rename_archive(phar_archive_data *phar, char *ext, zend_bool c
|
|||
basepath = estrndup(oldpath, strlen(oldpath) - strlen(oldname));
|
||||
phar->fname_len = spprintf(&newpath, 0, "%s%s", basepath, newname);
|
||||
phar->fname = newpath;
|
||||
phar->ext = newpath + phar->fname_len - strlen(ext) - 1;
|
||||
efree(basepath);
|
||||
efree(newname);
|
||||
|
||||
|
@ -1926,6 +1950,7 @@ static zval *phar_rename_archive(phar_archive_data *phar, char *ext, zend_bool c
|
|||
phar->fp = NULL;
|
||||
phar_destroy_phar_data(phar TSRMLS_CC);
|
||||
phar = *pphar;
|
||||
phar->refcount++;
|
||||
newpath = oldpath;
|
||||
goto its_ok;
|
||||
}
|
||||
|
@ -1963,7 +1988,7 @@ its_ok:
|
|||
phar->alias_len = 0;
|
||||
}
|
||||
|
||||
if (SUCCESS != zend_hash_update(&(PHAR_GLOBALS->phar_fname_map), newpath, phar->fname_len, (void*)&phar, sizeof(phar_archive_data*), NULL)) {
|
||||
if ((!pphar || phar == *pphar) && SUCCESS != zend_hash_update(&(PHAR_GLOBALS->phar_fname_map), newpath, phar->fname_len, (void*)&phar, sizeof(phar_archive_data*), NULL)) {
|
||||
efree(oldpath);
|
||||
zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Unable to add newly converted phar \"%s\" to the list of phars", phar->fname);
|
||||
return NULL;
|
||||
|
@ -4451,6 +4476,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_phar___construct, 0, 0, 1)
|
|||
ZEND_ARG_INFO(0, filename)
|
||||
ZEND_ARG_INFO(0, flags)
|
||||
ZEND_ARG_INFO(0, alias)
|
||||
ZEND_ARG_INFO(0, fileformat)
|
||||
ZEND_END_ARG_INFO();
|
||||
|
||||
static
|
||||
|
|
|
@ -141,6 +141,7 @@ int phar_open_or_create_tar(char *fname, int fname_len, char *alias, int alias_l
|
|||
|
||||
if (phar->is_brandnew) {
|
||||
phar->is_tar = 1;
|
||||
phar->is_zip = 0;
|
||||
phar->internal_file_start = 0;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
@ -422,6 +423,13 @@ int phar_open_tarfile(php_stream* fp, char *fname, int fname_len, char *alias, i
|
|||
#endif
|
||||
myphar->fname_len = fname_len;
|
||||
p = strrchr(myphar->fname, '/');
|
||||
|
||||
if (zend_hash_exists(&(myphar->manifest), ".phar/stub.php", sizeof(".phar/stub.php")-1)) {
|
||||
myphar->is_data = 0;
|
||||
} else {
|
||||
myphar->is_data = 1;
|
||||
}
|
||||
|
||||
if (p) {
|
||||
myphar->ext = memchr(p, '.', (myphar->fname + fname_len) - p);
|
||||
if (myphar->ext == p) {
|
||||
|
|
|
@ -1171,9 +1171,14 @@ phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, in
|
|||
if (!phar->manifest.arBuckets) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (is_dir) {
|
||||
if (!path_len || path_len == 1) {
|
||||
return NULL;
|
||||
}
|
||||
path_len--;
|
||||
}
|
||||
|
||||
if (SUCCESS == zend_hash_find(&phar->manifest, path, path_len, (void**)&entry)) {
|
||||
if (entry->is_deleted) {
|
||||
/* entry is deleted, but has not been flushed to disk yet */
|
||||
|
|
|
@ -443,6 +443,13 @@ foundit:
|
|||
zend_hash_add(&mydata->manifest, entry.filename, entry.filename_len, (void *)&entry,sizeof(phar_entry_info), NULL);
|
||||
}
|
||||
mydata->fp = fp;
|
||||
|
||||
if (zend_hash_exists(&(mydata->manifest), ".phar/stub.php", sizeof(".phar/stub.php")-1)) {
|
||||
mydata->is_data = 0;
|
||||
} else {
|
||||
mydata->is_data = 1;
|
||||
}
|
||||
|
||||
zend_hash_add(&(PHAR_GLOBALS->phar_fname_map), mydata->fname, fname_len, (void*)&mydata, sizeof(phar_archive_data*), NULL);
|
||||
if (actual_alias) {
|
||||
phar_archive_data **fd_ptr;
|
||||
|
@ -522,6 +529,7 @@ int phar_open_or_create_zip(char *fname, int fname_len, char *alias, int alias_l
|
|||
if (phar->is_brandnew) {
|
||||
phar->internal_file_start = 0;
|
||||
phar->is_zip = 1;
|
||||
phar->is_tar = 0;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue