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) {
|
if (pphar) {
|
||||||
*pphar = phar;
|
*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)) {
|
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);
|
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)) {
|
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);
|
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) {
|
if (is_data) {
|
||||||
alias = NULL;
|
alias = NULL;
|
||||||
alias_len = 0;
|
alias_len = 0;
|
||||||
|
mydata->is_data = 1;
|
||||||
|
/* assume tar format, PharData can specify other */
|
||||||
|
mydata->is_tar = 1;
|
||||||
} else {
|
} else {
|
||||||
phar_archive_data **fd_ptr;
|
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]])
|
/* {{{ proto void Phar::__construct(string fname [, int flags [, string alias]])
|
||||||
* Construct a Phar archive object
|
* 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
|
* Construct a PharData archive object
|
||||||
*/
|
*/
|
||||||
PHP_METHOD(Phar, __construct)
|
PHP_METHOD(Phar, __construct)
|
||||||
|
@ -1130,22 +1130,13 @@ PHP_METHOD(Phar, __construct)
|
||||||
#else
|
#else
|
||||||
char *fname, *alias = NULL, *error, *arch = NULL, *entry = NULL, *save_fname, *objname;
|
char *fname, *alias = NULL, *error, *arch = NULL, *entry = NULL, *save_fname, *objname;
|
||||||
int fname_len, alias_len = 0, arch_len, entry_len, is_data;
|
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_object *phar_obj;
|
||||||
phar_archive_data *phar_data;
|
phar_archive_data *phar_data;
|
||||||
zval *zobj = getThis(), arg1, arg2;
|
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);
|
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);
|
PHAR_STR(phar_obj->std.ce->name, objname);
|
||||||
|
|
||||||
if (!strncmp(objname, "PharData", 8)) {
|
if (!strncmp(objname, "PharData", 8)) {
|
||||||
|
@ -1154,6 +1145,21 @@ PHP_METHOD(Phar, __construct)
|
||||||
is_data = 0;
|
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)) {
|
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 */
|
/* use arch (the basename for the archive) for fname instead of fname */
|
||||||
/* this allows support for RecursiveDirectoryIterator of subdirectories */
|
/* this allows support for RecursiveDirectoryIterator of subdirectories */
|
||||||
|
@ -1193,11 +1199,28 @@ PHP_METHOD(Phar, __construct)
|
||||||
return;
|
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) {
|
if (fname == arch) {
|
||||||
efree(arch);
|
efree(arch);
|
||||||
fname = save_fname;
|
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;
|
is_data = phar_data->is_data;
|
||||||
++(phar_data->refcount);
|
++(phar_data->refcount);
|
||||||
phar_obj->arc.archive = phar_data;
|
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;
|
char *error;
|
||||||
const char *pcr_error;
|
const char *pcr_error;
|
||||||
int ext_len = ext ? strlen(ext) : 0;
|
int ext_len = ext ? strlen(ext) : 0;
|
||||||
phar_archive_data **pphar;
|
phar_archive_data **pphar = NULL;
|
||||||
|
|
||||||
if (!ext) {
|
if (!ext) {
|
||||||
if (phar->is_zip) {
|
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));
|
basepath = estrndup(oldpath, strlen(oldpath) - strlen(oldname));
|
||||||
phar->fname_len = spprintf(&newpath, 0, "%s%s", basepath, newname);
|
phar->fname_len = spprintf(&newpath, 0, "%s%s", basepath, newname);
|
||||||
phar->fname = newpath;
|
phar->fname = newpath;
|
||||||
|
phar->ext = newpath + phar->fname_len - strlen(ext) - 1;
|
||||||
efree(basepath);
|
efree(basepath);
|
||||||
efree(newname);
|
efree(newname);
|
||||||
|
|
||||||
|
@ -1926,6 +1950,7 @@ static zval *phar_rename_archive(phar_archive_data *phar, char *ext, zend_bool c
|
||||||
phar->fp = NULL;
|
phar->fp = NULL;
|
||||||
phar_destroy_phar_data(phar TSRMLS_CC);
|
phar_destroy_phar_data(phar TSRMLS_CC);
|
||||||
phar = *pphar;
|
phar = *pphar;
|
||||||
|
phar->refcount++;
|
||||||
newpath = oldpath;
|
newpath = oldpath;
|
||||||
goto its_ok;
|
goto its_ok;
|
||||||
}
|
}
|
||||||
|
@ -1963,7 +1988,7 @@ its_ok:
|
||||||
phar->alias_len = 0;
|
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);
|
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);
|
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;
|
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, filename)
|
||||||
ZEND_ARG_INFO(0, flags)
|
ZEND_ARG_INFO(0, flags)
|
||||||
ZEND_ARG_INFO(0, alias)
|
ZEND_ARG_INFO(0, alias)
|
||||||
|
ZEND_ARG_INFO(0, fileformat)
|
||||||
ZEND_END_ARG_INFO();
|
ZEND_END_ARG_INFO();
|
||||||
|
|
||||||
static
|
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) {
|
if (phar->is_brandnew) {
|
||||||
phar->is_tar = 1;
|
phar->is_tar = 1;
|
||||||
|
phar->is_zip = 0;
|
||||||
phar->internal_file_start = 0;
|
phar->internal_file_start = 0;
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -422,6 +423,13 @@ int phar_open_tarfile(php_stream* fp, char *fname, int fname_len, char *alias, i
|
||||||
#endif
|
#endif
|
||||||
myphar->fname_len = fname_len;
|
myphar->fname_len = fname_len;
|
||||||
p = strrchr(myphar->fname, '/');
|
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) {
|
if (p) {
|
||||||
myphar->ext = memchr(p, '.', (myphar->fname + fname_len) - p);
|
myphar->ext = memchr(p, '.', (myphar->fname + fname_len) - p);
|
||||||
if (myphar->ext == 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) {
|
if (!phar->manifest.arBuckets) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_dir) {
|
if (is_dir) {
|
||||||
|
if (!path_len || path_len == 1) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
path_len--;
|
path_len--;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SUCCESS == zend_hash_find(&phar->manifest, path, path_len, (void**)&entry)) {
|
if (SUCCESS == zend_hash_find(&phar->manifest, path, path_len, (void**)&entry)) {
|
||||||
if (entry->is_deleted) {
|
if (entry->is_deleted) {
|
||||||
/* entry is deleted, but has not been flushed to disk yet */
|
/* 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);
|
zend_hash_add(&mydata->manifest, entry.filename, entry.filename_len, (void *)&entry,sizeof(phar_entry_info), NULL);
|
||||||
}
|
}
|
||||||
mydata->fp = fp;
|
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);
|
zend_hash_add(&(PHAR_GLOBALS->phar_fname_map), mydata->fname, fname_len, (void*)&mydata, sizeof(phar_archive_data*), NULL);
|
||||||
if (actual_alias) {
|
if (actual_alias) {
|
||||||
phar_archive_data **fd_ptr;
|
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) {
|
if (phar->is_brandnew) {
|
||||||
phar->internal_file_start = 0;
|
phar->internal_file_start = 0;
|
||||||
phar->is_zip = 1;
|
phar->is_zip = 1;
|
||||||
|
phar->is_tar = 0;
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue