1. Fixed phar_rename_archive to no longer remove everything after a "." in the filename
2. Removed unused "zend_bool compress" parameter
3. Added Test
4. Fixed tests that had a work around for this problem
- phar:
. Fixed bug #74383 phar method parameters reflection correction. (mhagstrand)
+ . Fixed bug #74196 (phar does not correctly handle names containing dots).
+ (mhagstrand)
- PHPDBG
. Added extended_value to opcode dump output. (Sara)
}
/* }}} */
-static zend_object *phar_rename_archive(phar_archive_data **sphar, char *ext, zend_bool compress) /* {{{ */
+static zend_object *phar_rename_archive(phar_archive_data **sphar, char *ext) /* {{{ */
{
const char *oldname = NULL;
phar_archive_data *phar = *sphar;
char *error;
const char *pcr_error;
int ext_len = ext ? strlen(ext) : 0;
- size_t new_len, oldname_len;
+ size_t new_len, oldname_len, phar_ext_len;
phar_archive_data *pphar = NULL;
php_stream_statbuf ssb;
+ int phar_ext_list_len, i = 0;
+ char *ext_pos = NULL;
+ /* Array of PHAR extensions, Must be in order, starting with longest
+ * ending with the shortest. */
+ char *phar_ext_list[] = {
+ ".phar.tar.bz2",
+ ".phar.tar.gz",
+ ".phar.php",
+ ".phar.bz2",
+ ".phar.zip",
+ ".phar.tar",
+ ".phar.gz",
+ ".tar.bz2",
+ ".tar.gz",
+ ".phar",
+ ".tar",
+ ".zip"
+ };
+
if (!ext) {
if (phar->is_zip) {
return NULL;
}
- if (ext[0] == '.') {
- ++ext;
- }
oldpath = estrndup(phar->fname, phar->fname_len);
if ((oldname = zend_memrchr(phar->fname, '/', phar->fname_len))) {
} else {
oldname = phar->fname;
}
- oldname_len = strlen(oldname);
+ oldname_len = strlen(oldname);
+ /* Copy the old name to create base for the new name */
basename = estrndup(oldname, oldname_len);
- spprintf(&newname, 0, "%s.%s", strtok(basename, "."), ext);
+
+ phar_ext_list_len = sizeof(phar_ext_list)/sizeof(phar_ext_list[0]);
+ /* Remove possible PHAR extensions */
+ /* phar_ext_list must be in order of longest extension to shortest */
+ for (i=0; i < phar_ext_list_len; i++) {
+ phar_ext_len = strlen(phar_ext_list[i]);
+ if (phar_ext_len && oldname_len > phar_ext_len) {
+ /* Check if the basename strings ends with the extension */
+ if (memcmp(phar_ext_list[i], basename + (oldname_len - phar_ext_len), phar_ext_len) == 0) {
+ ext_pos = basename + (oldname_len - phar_ext_len);
+ ext_pos[0] = '\0';
+ break;
+ }
+ }
+ ext_pos = NULL;
+ }
+
+ /* If no default PHAR extension found remove the last extension */
+ if (!ext_pos) {
+ ext_pos = strrchr(basename, '.');
+ if (ext_pos) {
+ ext_pos[0] = '\0';
+ }
+ }
+ ext_pos = NULL;
+
+ if (ext[0] == '.') {
+ ++ext;
+ }
+ /* Append extension to the basename */
+ spprintf(&newname, 0, "%s.%s", basename, ext);
efree(basename);
basepath = estrndup(oldpath, (strlen(oldpath) - oldname_len));
phar_add_virtual_dirs(phar, newentry.filename, newentry.filename_len);
} ZEND_HASH_FOREACH_END();
- if ((ret = phar_rename_archive(&phar, ext, 0))) {
+ if ((ret = phar_rename_archive(&phar, ext))) {
return ret;
} else {
if(phar != NULL) {
$phar = new PharData($fname);
$phar['x'] = 'hi';
try {
- $phar->convertToData(Phar::ZIP, Phar::NONE, '.2.phar.zip');
+ $phar->convertToData(Phar::ZIP, Phar::NONE, 'phar.zip');
} catch (BadMethodCallException $e) {
echo $e->getMessage(),"\n";
}
--CLEAN--
<?php unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.zip');?>
--EXPECTF--
-data phar "%sbug48377.2.phar.zip" has invalid extension 2.phar.zip
-===DONE===
\ No newline at end of file
+data phar "%sbug48377.2.phar.zip" has invalid extension phar.zip
+===DONE===
--- /dev/null
+--TEST--
+PHP bug #74196: PharData->decompress() does not correctly support dot names
+--SKIPIF--
+<?php if (!extension_loaded("phar")) die("skip"); ?>
+<?php if (!extension_loaded("zlib")) die("skip"); ?>
+--INI--
+phar.require_hash=0
+phar.readonly=0
+--FILE--
+<?php
+$fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.1.2.3.phar.tar.gz';
+$decompressed_name = str_replace( ".gz", "", $fname);
+var_dump(file_exists($fname));
+
+$phar = new Phar($fname);
+$phar->decompress();
+var_dump(file_exists($decompressed_name));
+unlink($decompressed_name);
+
+?>
+--EXPECTF--
+bool(true)
+bool(true)
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.2.phar.zip');
+unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.2.2.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') . '.2.2.2.3.phar.zip');
unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.3.phar.tar');
unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.3.phar');
?>
} catch(Exception $e) {
echo $e->getMessage()."\n";
}
-
?>
===DONE===
--CLEAN--
-<?php
+<?php
+echo dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar.gz' . "\n";
+
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') . '.1.2.tar');
unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.zip');
unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.1.zip');
+
?>
--EXPECT--
=================== new PharData() ==================
NULL
================= convertToPhar() ====================
Cannot write out executable phar archive, phar is read-only
-===DONE===
\ No newline at end of file
+===DONE===
$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, '.phar.tar');
unset($a);
Phar::unlinkArchive($fname2);
$b['foo/stat.php'] = '<?php
dir
bool(true)
bool(false)
-===DONE===
\ No newline at end of file
+===DONE===