From 062faf81e4a9e0f412c98a8309d42fb92e2a5737 Mon Sep 17 00:00:00 2001 From: Ralph Schindler Date: Tue, 5 Mar 2013 13:38:35 -0600 Subject: [PATCH 1/4] Fixed issue #60953 Altered phar_rename_archive() such that it will look for '.phar' first, then '.tar' && '.zip' in data phar files before falling back on finding anything after the first '.' in a file extension --- ext/phar/phar_object.c | 28 ++++++++++++++++------- ext/phar/tests/bug60953.phpt | 26 +++++++++++++++++++++ ext/phar/tests/phar_convert_repeated.phpt | 20 ++++++++-------- ext/phar/tests/stat2_5.3.phpt | 2 +- 4 files changed, 57 insertions(+), 19 deletions(-) create mode 100644 ext/phar/tests/bug60953.phpt diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index e276613209f05..79771b925795c 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -2004,7 +2004,8 @@ static zend_object *phar_rename_archive(phar_archive_data *phar, char *ext, zend char *oldpath = NULL; char *basename = NULL, *basepath = NULL; char *newname = NULL, *newpath = NULL; - zval ret, arg1; + char *oldname_ext = NULL; + zval *ret, arg1; zend_class_entry *ce; char *error; const char *pcr_error; @@ -2074,18 +2075,29 @@ static zend_object *phar_rename_archive(phar_archive_data *phar, char *ext, zend } oldpath = estrndup(phar->fname, phar->fname_len); - if ((oldname = zend_memrchr(phar->fname, '/', phar->fname_len))) { - ++oldname; - } else { - oldname = phar->fname; - } + oldname = zend_memrchr(phar->fname, '/', phar->fname_len); + ++oldname; oldname_len = strlen(oldname); basename = estrndup(oldname, oldname_len); - spprintf(&newname, 0, "%s.%s", strtok(basename, "."), ext); - efree(basename); + + /* find extension name, .phar for executable phars, .zip* and .tar* for data only phars */ + oldname_ext = strstr(basename, ".phar"); + if (oldname_ext == NULL && phar->is_data) { + oldname_ext = strstr(basename, ".tar"); + if (oldname_ext == NULL) { + oldname_ext = strstr(basename, ".zip"); + } + } + if (oldname_ext == NULL) { + /* old behavior for BC, take anything after first . */ + oldname_ext = strstr(basename, "."); + } + newname = strndup(basename, (oldname_ext - basename)); + spprintf(&newname, 0, "%s.%s", newname, ext); + efree(basename); basepath = estrndup(oldpath, (strlen(oldpath) - oldname_len)); phar->fname_len = spprintf(&newpath, 0, "%s%s", basepath, newname); diff --git a/ext/phar/tests/bug60953.phpt b/ext/phar/tests/bug60953.phpt new file mode 100644 index 0000000000000..2fa356c6d4347 --- /dev/null +++ b/ext/phar/tests/bug60953.phpt @@ -0,0 +1,26 @@ +--TEST-- +Phar: rename test +--SKIPIF-- + +--INI-- +phar.readonly=0 +phar.require_hash=0 +--FILE-- +stopBuffering(); +unset($phar); +$phar = new Phar(__DIR__ . '/package-1.2.3.phar'); +$phar->convertToExecutable(Phar::TAR, Phar::GZ); +var_dump(file_exists(__DIR__ . '/package-1.2.3.phar')); +var_dump(file_exists(__DIR__ . '/package-1.2.3.phar.tar.gz')); +?> +--CLEAN-- + +--EXPECTF-- +bool(true) +bool(true) \ No newline at end of file diff --git a/ext/phar/tests/phar_convert_repeated.phpt b/ext/phar/tests/phar_convert_repeated.phpt index e4b1fe41d770c..79360b2a4be0b 100644 --- a/ext/phar/tests/phar_convert_repeated.phpt +++ b/ext/phar/tests/phar_convert_repeated.phpt @@ -50,7 +50,7 @@ var_dump($phar->getAlias()); echo "================= convertToPhar() ====================\n"; -$phar = $phar->convertToExecutable(Phar::PHAR, Phar::NONE, '.2.phar'); +$phar = $phar->convertToExecutable(Phar::PHAR, Phar::NONE, '.phar.pharfile'); var_dump($phar->isFileFormat(Phar::PHAR)); var_dump($phar->isFileFormat(Phar::TAR)); var_dump($phar->isFileFormat(Phar::ZIP)); @@ -59,7 +59,7 @@ var_dump($phar->getAlias()); echo "================= convertToZip() =====================\n"; -$phar = $phar->convertToExecutable(Phar::ZIP, Phar::NONE, '.2.phar.zip'); +$phar = $phar->convertToExecutable(Phar::ZIP, Phar::NONE, '.phar.zipfile'); var_dump($phar->isFileFormat(Phar::PHAR)); var_dump($phar->isFileFormat(Phar::TAR)); var_dump($phar->isFileFormat(Phar::ZIP)); @@ -68,7 +68,7 @@ var_dump($phar->getAlias()); echo "================= convertToTar() =====================\n"; -$phar = $phar->convertToExecutable(Phar::TAR, Phar::NONE, '2.phar.tar'); +$phar = $phar->convertToExecutable(Phar::TAR, Phar::NONE, '.phar.tarfile'); var_dump($phar->isFileFormat(Phar::PHAR)); var_dump($phar->isFileFormat(Phar::TAR)); var_dump($phar->isFileFormat(Phar::ZIP)); @@ -77,7 +77,7 @@ var_dump($phar->getAlias()); echo "================= convertToZip() =====================\n"; -$phar = $phar->convertToExecutable(Phar::ZIP, Phar::NONE, '3.phar.zip'); +$phar = $phar->convertToExecutable(Phar::ZIP, Phar::NONE, '.phar.zip2'); var_dump($phar->isFileFormat(Phar::PHAR)); var_dump($phar->isFileFormat(Phar::TAR)); var_dump($phar->isFileFormat(Phar::ZIP)); @@ -91,12 +91,12 @@ var_dump($phar->getAlias()); unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar.zip'); unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar.tar'); unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar'); -unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.2.phar.zip'); -unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.2.phar.tar'); -unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.2.phar'); -unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.3.phar.zip'); -unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.3.phar.tar'); -unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.3.phar'); +unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar.zipfile'); +unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar.tarfile'); +unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar.pharfile'); +unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar.zipfile'); +unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar.tarfile'); +unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar.zip2'); ?> --EXPECTF-- =================== new Phar() ======================= diff --git a/ext/phar/tests/stat2_5.3.phpt b/ext/phar/tests/stat2_5.3.phpt index aba2a6417de55..378ae7eca567b 100644 --- a/ext/phar/tests/stat2_5.3.phpt +++ b/ext/phar/tests/stat2_5.3.phpt @@ -17,7 +17,7 @@ $fname2 = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.tar'; $fname3 = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.tar'; copy(dirname(__FILE__) . '/tar/files/links.tar', $fname2); $a = new PharData($fname2); -$b = $a->convertToExecutable(Phar::TAR, Phar::NONE, '.3.phar.tar'); +$b = $a->convertToExecutable(Phar::TAR, Phar::NONE); unset($a); Phar::unlinkArchive($fname2); $b['foo/stat.php'] = ' Date: Sun, 1 Sep 2013 09:24:36 -0500 Subject: [PATCH 2/4] Updated phar_object.c to use separate variables and estrndup() --- ext/phar/phar_object.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index 79771b925795c..fbd528f723a85 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -2003,7 +2003,7 @@ static zend_object *phar_rename_archive(phar_archive_data *phar, char *ext, zend const char *oldname = NULL; char *oldpath = NULL; char *basename = NULL, *basepath = NULL; - char *newname = NULL, *newpath = NULL; + char *newbasename = NULL, *newname = NULL, *newpath = NULL; char *oldname_ext = NULL; zval *ret, arg1; zend_class_entry *ce; @@ -2095,8 +2095,8 @@ static zend_object *phar_rename_archive(phar_archive_data *phar, char *ext, zend oldname_ext = strstr(basename, "."); } - newname = strndup(basename, (oldname_ext - basename)); - spprintf(&newname, 0, "%s.%s", newname, ext); + newbasename = estrndup(basename, (oldname_ext - basename)); + spprintf(&newname, 0, "%s.%s", newbasename, ext); efree(basename); basepath = estrndup(oldpath, (strlen(oldpath) - oldname_len)); @@ -2104,6 +2104,7 @@ static zend_object *phar_rename_archive(phar_archive_data *phar, char *ext, zend phar->fname = newpath; phar->ext = newpath + phar->fname_len - strlen(ext) - 1; efree(basepath); + efree(newbasename); efree(newname); if (PHAR_G(manifest_cached) && NULL != (pphar = zend_hash_str_find_ptr(&cached_phars, newpath, phar->fname_len))) { From a7a9f4c57918aef4367e43d6bd50860dc3ffc2d0 Mon Sep 17 00:00:00 2001 From: Ralph Schindler Date: Thu, 10 Oct 2013 12:18:55 -0700 Subject: [PATCH 3/4] Fixed tab->space --- ext/phar/phar_object.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index fbd528f723a85..adc20d0f05d07 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -2104,7 +2104,7 @@ static zend_object *phar_rename_archive(phar_archive_data *phar, char *ext, zend phar->fname = newpath; phar->ext = newpath + phar->fname_len - strlen(ext) - 1; efree(basepath); - efree(newbasename); + efree(newbasename); efree(newname); if (PHAR_G(manifest_cached) && NULL != (pphar = zend_hash_str_find_ptr(&cached_phars, newpath, phar->fname_len))) { From 788ac6750fa9374bdb3c1f6446e8ee66544d697a Mon Sep 17 00:00:00 2001 From: Ralph Schindler Date: Mon, 16 Mar 2015 11:50:51 -0500 Subject: [PATCH 4/4] PR #297 / Bug #60953 - removed backwards compatibility file name extension code - fixed all tests and their cleanup to reflect new file name suffixes --- ext/phar/phar_object.c | 21 ++++++++++++--------- ext/phar/tests/bug48377.2.phpt | 4 ++-- ext/phar/tests/phar_convert_repeated_b.phpt | 2 +- ext/phar/tests/stat2_5.3.phpt | 3 +-- 4 files changed, 16 insertions(+), 14 deletions(-) diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index adc20d0f05d07..40d4539ff5424 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -2005,7 +2005,7 @@ static zend_object *phar_rename_archive(phar_archive_data *phar, char *ext, zend char *basename = NULL, *basepath = NULL; char *newbasename = NULL, *newname = NULL, *newpath = NULL; char *oldname_ext = NULL; - zval *ret, arg1; + zval ret, arg1; zend_class_entry *ce; char *error; const char *pcr_error; @@ -2081,22 +2081,26 @@ static zend_object *phar_rename_archive(phar_archive_data *phar, char *ext, zend basename = estrndup(oldname, oldname_len); - /* find extension name, .phar for executable phars, .zip* and .tar* for data only phars */ + /* find extension name: .phar suffixed with anything and .zip* and .tar* without .phar for data archives */ oldname_ext = strstr(basename, ".phar"); - if (oldname_ext == NULL && phar->is_data) { + if (oldname_ext == NULL) { oldname_ext = strstr(basename, ".tar"); if (oldname_ext == NULL) { - oldname_ext = strstr(basename, ".zip"); + oldname_ext = strstr(basename, ".tgz"); + if (oldname_ext == NULL) { + oldname_ext = strstr(basename, ".zip"); + } } } - if (oldname_ext == NULL) { - /* old behavior for BC, take anything after first . */ - oldname_ext = strstr(basename, "."); + newbasename = basename; + + if (oldname_ext != NULL) { + newbasename = estrndup(basename, (oldname_ext - basename)); } - newbasename = estrndup(basename, (oldname_ext - basename)); spprintf(&newname, 0, "%s.%s", newbasename, ext); + efree(newbasename); efree(basename); basepath = estrndup(oldpath, (strlen(oldpath) - oldname_len)); @@ -2104,7 +2108,6 @@ static zend_object *phar_rename_archive(phar_archive_data *phar, char *ext, zend phar->fname = newpath; phar->ext = newpath + phar->fname_len - strlen(ext) - 1; efree(basepath); - efree(newbasename); efree(newname); if (PHAR_G(manifest_cached) && NULL != (pphar = zend_hash_str_find_ptr(&cached_phars, newpath, phar->fname_len))) { diff --git a/ext/phar/tests/bug48377.2.phpt b/ext/phar/tests/bug48377.2.phpt index be2a0e1036080..6f63dc3f42884 100644 --- a/ext/phar/tests/bug48377.2.phpt +++ b/ext/phar/tests/bug48377.2.phpt @@ -12,7 +12,7 @@ $fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.zip'; $phar = new PharData($fname); $phar['x'] = 'hi'; try { - $phar->convertToData(Phar::ZIP, Phar::NONE, '.2.phar.zip'); + $phar->convertToData(Phar::ZIP, Phar::NONE, 'zip'); } catch (BadMethodCallException $e) { echo $e->getMessage(),"\n"; } @@ -21,5 +21,5 @@ try { --CLEAN-- --EXPECTF-- -data phar "%sbug48377.2.phar.zip" has invalid extension 2.phar.zip +Unable to add newly converted phar "%sbug48377.2.zip" to the list of phars, a phar with that name already exists ===DONE=== \ No newline at end of file diff --git a/ext/phar/tests/phar_convert_repeated_b.phpt b/ext/phar/tests/phar_convert_repeated_b.phpt index 10e6973254b6c..51b979fef2f63 100644 --- a/ext/phar/tests/phar_convert_repeated_b.phpt +++ b/ext/phar/tests/phar_convert_repeated_b.phpt @@ -82,9 +82,9 @@ try { unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar.gz'); unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.tar.gz'); unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.tar'); -unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.2.tar'); unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.zip'); unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.1.zip'); +unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.1.2.tar'); ?> --EXPECT-- =================== new PharData() ================== diff --git a/ext/phar/tests/stat2_5.3.phpt b/ext/phar/tests/stat2_5.3.phpt index 378ae7eca567b..d65e8ddc367a4 100644 --- a/ext/phar/tests/stat2_5.3.phpt +++ b/ext/phar/tests/stat2_5.3.phpt @@ -14,7 +14,6 @@ is_link(); var_dump(is_file(__FILE__)); $fname2 = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.tar'; -$fname3 = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.tar'; copy(dirname(__FILE__) . '/tar/files/links.tar', $fname2); $a = new PharData($fname2); $b = $a->convertToExecutable(Phar::TAR, Phar::NONE); @@ -33,7 +32,7 @@ $b->addEmptyDir('foo/bar/blah'); $b->setStub(' ===DONE=== --CLEAN--