com php-src: Fix for Bug 74196: PharData->decompress() does not correctly support dot names: NEWS ext/phar/phar_object.c ext/phar/t ests/bug48377.2.phpt ext/phar/tests/bug74 196.1.2.3.phar.tar.gz ext/phar/tests/ bug74196.phpt ext/phar/tests/phar_convert_rep eated.phpt ext/phar/tests/phar_convert_repeated_b.p hpt ext/phar/tests/stat2_5.3.phpt

[email protected] (Joe Watkins)
Newsgroups php.cvs
Message-ID <[email protected]>
Commit:    a9fdf3d6b47ba0bbb35f1bc5b0165574ce29f132
Author:    Mitch Hagstrand <[email protected]>         Fri, 7 Apr 2017 16:52:12 -0700
Committer: Joe Watkins <[email protected]>      Mon, 10 Apr 2017 06:43:26 +0100
Parents:   b0f9dba2d97ddb794cb157e1276c3b608bc18277
Branches:  master

Link:       http://git.php.net/?p=php-src.git;a=commitdiff;h=a9fdf3d6b47ba0bbb35f1bc5b0165574ce29f132

Log:
Fix for Bug 74196: PharData->decompress() does not correctly support dot names

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

Bugs:
https://bugs.php.net/74196

Changed paths:
  M  NEWS
  M  ext/phar/phar_object.c
  M  ext/phar/tests/bug48377.2.phpt
  A  ext/phar/tests/bug74196.1.2.3.phar.tar.gz
  A  ext/phar/tests/bug74196.phpt
  M  ext/phar/tests/phar_convert_repeated.phpt
  M  ext/phar/tests/phar_convert_repeated_b.phpt
  M  ext/phar/tests/stat2_5.3.phpt
diff_a9fdf3d6b47ba0bbb35f1bc5b0165574ce29f132.txt (text/plain, 8.7 KB)
diff --git a/NEWS b/NEWS
index a69bdc8..eae6a81 100644
--- a/NEWS
+++ b/NEWS
@@ -140,6 +140,8 @@ PHP                                                                        NEWS
 
 - 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)
diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c
index 8e9233a..f5973b5 100644
--- a/ext/phar/phar_object.c
+++ b/ext/phar/phar_object.c
@@ -2019,7 +2019,7 @@ static int phar_copy_file_contents(phar_entry_info *entry, php_stream *fp) /* {{
 }
 /* }}} */
 
-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;
@@ -2031,10 +2031,29 @@ static zend_object *phar_rename_archive(phar_archive_data **sphar, char *ext, ze
 	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) {
 
@@ -2091,9 +2110,6 @@ static zend_object *phar_rename_archive(phar_archive_data **sphar, char *ext, ze
 		return NULL;
 	}
 
-	if (ext[0] == '.') {
-		++ext;
-	}
 
 	oldpath = estrndup(phar->fname, phar->fname_len);
 	if ((oldname = zend_memrchr(phar->fname, '/', phar->fname_len))) {
@@ -2101,10 +2117,41 @@ static zend_object *phar_rename_archive(phar_archive_data **sphar, char *ext, ze
 	} 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));
@@ -2321,7 +2368,7 @@ no_copy:
 		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) {
diff --git a/ext/phar/tests/bug48377.2.phpt b/ext/phar/tests/bug48377.2.phpt
index be2a0e1..380f3e3 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, 'phar.zip');
 } catch (BadMethodCallException $e) {
 	echo $e->getMessage(),"\n";
 }
@@ -21,5 +21,5 @@ try {
 --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===
diff --git a/ext/phar/tests/bug74196.1.2.3.phar.tar.gz b/ext/phar/tests/bug74196.1.2.3.phar.tar.gz
new file mode 100644
index 0000000..e2ac1e0
Binary files /dev/null and b/ext/phar/tests/bug74196.1.2.3.phar.tar.gz differ
diff --git a/ext/phar/tests/bug74196.phpt b/ext/phar/tests/bug74196.phpt
new file mode 100644
index 0000000..7a8e923
--- /dev/null
+++ b/ext/phar/tests/bug74196.phpt
@@ -0,0 +1,23 @@
+--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)
diff --git a/ext/phar/tests/phar_convert_repeated.phpt b/ext/phar/tests/phar_convert_repeated.phpt
index b2ef195..2d22c70 100644
--- a/ext/phar/tests/phar_convert_repeated.phpt
+++ b/ext/phar/tests/phar_convert_repeated.phpt
@@ -91,10 +91,10 @@ 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.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');
 ?>
diff --git a/ext/phar/tests/phar_convert_repeated_b.phpt b/ext/phar/tests/phar_convert_repeated_b.phpt
index 10e6973..647bb84 100644
--- a/ext/phar/tests/phar_convert_repeated_b.phpt
+++ b/ext/phar/tests/phar_convert_repeated_b.phpt
@@ -74,17 +74,19 @@ try {
 } 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() ==================
@@ -115,4 +117,4 @@ string(0) ""
 NULL
 ================= convertToPhar() ====================
 Cannot write out executable phar archive, phar is read-only
-===DONE===
\ No newline at end of file
+===DONE===
diff --git a/ext/phar/tests/stat2_5.3.phpt b/ext/phar/tests/stat2_5.3.phpt
index aba2a641..6a3f2bf 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, '.phar.tar');
 unset($a);
 Phar::unlinkArchive($fname2);
 $b['foo/stat.php'] = '<?php
@@ -58,4 +58,4 @@ bool(false)
 dir
 bool(true)
 bool(false)
-===DONE===
\ No newline at end of file
+===DONE===
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.