summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristoph M. Becker <cmbecker69@gmx.de>2020-12-18 18:05:52 +0100
committerChristoph M. Becker <cmbecker69@gmx.de>2021-01-19 10:28:54 +0100
commit68f5289e9e84b12b1a9ad671657702ce9a65a1e1 (patch)
treefca4944d7564ad8232a8431252e633d133cf8dd3
parent38ad37ad435511391e16983794022a8d1e7d6a14 (diff)
downloadphp-git-68f5289e9e84b12b1a9ad671657702ce9a65a1e1.tar.gz
Fix #69279: Compressed ZIP Phar extractTo() creates garbage files
When extracting compressed files from an uncompressed Phar, we must not use the direct file pointer, but rather get an uncompressed file pointer. We also add a test to show that deflated and stored entries are properly extracted. This also fixes #79912, which appears to be a duplicate of #69279. Co-authored-by: Anna Filina <afilina@gmail.com> Closes GH-6599.
-rw-r--r--NEWS2
-rw-r--r--ext/phar/phar_object.c2
-rw-r--r--ext/phar/tests/bug69279.phpt29
-rw-r--r--ext/phar/tests/bug69279a.phpt26
-rw-r--r--ext/phar/tests/bug69279a.zipbin0 -> 719 bytes
-rw-r--r--ext/phar/tests/bug79912.phpt35
6 files changed, 93 insertions, 1 deletions
diff --git a/NEWS b/NEWS
index 24eaddce3e..c74a329030 100644
--- a/NEWS
+++ b/NEWS
@@ -25,6 +25,8 @@ PHP NEWS
- Phar:
. Fixed bug #77565 (Incorrect locator detection in ZIP-based phars). (cmb)
+ . Fixed bug #69279 (Compressed ZIP Phar extractTo() creates garbage files).
+ (cmb)
07 Jan 2021, PHP 7.4.14
diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c
index db70f4cc71..34da571a89 100644
--- a/ext/phar/phar_object.c
+++ b/ext/phar/phar_object.c
@@ -4275,7 +4275,7 @@ static int phar_extract_file(zend_bool overwrite, phar_entry_info *entry, char *
return FAILURE;
}
- if (!phar_get_efp(entry, 0)) {
+ if ((phar_get_fp_type(entry) == PHAR_FP && (entry->flags & PHAR_ENT_COMPRESSION_MASK)) || !phar_get_efp(entry, 0)) {
if (FAILURE == phar_open_entry_fp(entry, error, 1)) {
if (error) {
spprintf(error, 4096, "Cannot extract \"%s\" to \"%s\", unable to open internal file pointer: %s", entry->filename, fullpath, *error);
diff --git a/ext/phar/tests/bug69279.phpt b/ext/phar/tests/bug69279.phpt
new file mode 100644
index 0000000000..6aeac12d3b
--- /dev/null
+++ b/ext/phar/tests/bug69279.phpt
@@ -0,0 +1,29 @@
+--TEST--
+Bug #69279 (Compressed ZIP Phar extractTo() creates garbage files)
+--SKIPIF--
+<?php
+if (!extension_loaded('phar')) die('skip phar extension not available');
+?>
+--INI--
+phar.readonly=0
+--FILE--
+<?php
+$w = new Phar(__DIR__ . "/bug69279.phar.zip");
+$w["bug69279.txt"] = "Sample content.";
+$w->compressFiles(Phar::GZ);
+unset($w);
+
+$r = new Phar(__DIR__ . "/bug69279.phar.zip");
+var_dump($r["bug69279.txt"]->isCompressed());
+
+$r->extractTo(__DIR__, NULL, TRUE);
+var_dump(file_get_contents(__DIR__ . "/bug69279.txt"));
+?>
+--EXPECT--
+bool(true)
+string(15) "Sample content."
+--CLEAN--
+<?php
+@unlink(__DIR__ . "/bug69279.txt");
+@unlink(__DIR__ . "/bug69279.phar.zip");
+?>
diff --git a/ext/phar/tests/bug69279a.phpt b/ext/phar/tests/bug69279a.phpt
new file mode 100644
index 0000000000..4a9db45238
--- /dev/null
+++ b/ext/phar/tests/bug69279a.phpt
@@ -0,0 +1,26 @@
+--TEST--
+Bug #69279 (Compressed ZIP Phar extractTo() creates garbage files)
+--SKIPIF--
+<?php
+if (!extension_loaded('phar')) die('skip phar extension not available');
+?>
+--FILE--
+<?php
+$phar = new PharData(__DIR__ . '/bug69279a.zip');
+mkdir(__DIR__ . '/bug69279a');
+var_dump($phar->extractTo(__DIR__ . '/bug69279a', null, true));
+var_dump(strncmp(file_get_contents(__DIR__ . '/bug69279a/1.txt'), 'Lorem ipsum', 11));
+var_dump(strncmp(file_get_contents(__DIR__ . '/bug69279a/2.txt'), 'foo', 3));
+var_dump(strncmp(file_get_contents(__DIR__ . '/bug69279a/3.txt'), 'Lorem ipsum', 11));
+?>
+--EXPECT--
+bool(true)
+int(0)
+int(0)
+int(0)
+--CLEAN--
+<?php
+@unlink(__DIR__ . '/bug69279a/1.txt');
+@unlink(__DIR__ . '/bug69279a/2.txt');
+@unlink(__DIR__ . '/bug69279a/3.txt');
+@rmdir(__DIR__ . '/bug69279a');
diff --git a/ext/phar/tests/bug69279a.zip b/ext/phar/tests/bug69279a.zip
new file mode 100644
index 0000000000..e45ac8b85a
--- /dev/null
+++ b/ext/phar/tests/bug69279a.zip
Binary files differ
diff --git a/ext/phar/tests/bug79912.phpt b/ext/phar/tests/bug79912.phpt
new file mode 100644
index 0000000000..7187b4f55e
--- /dev/null
+++ b/ext/phar/tests/bug79912.phpt
@@ -0,0 +1,35 @@
+--TEST--
+Bug #79912 (Phar::decompressFiles not working)
+--SKIPIF--
+<?php
+if (!extension_loaded('phar')) die('skip phar extension is not available');
+?>
+--INI--
+phar.readonly=0
+--FILE--
+<?php
+$phar = new Phar(__DIR__ . "/bug79912.phar");
+$phar->addFromString("test.txt", "This is a test file.This is a test file.This is a test file.");
+$file = $phar["test.txt"];
+var_dump($file->compress(Phar::GZ)); //true (success)
+var_dump($file->getContent());
+var_dump($file->isCompressed()); //true (the file is compressed)
+var_dump($phar->decompressFiles()); //true (success)
+var_dump($file->isCompressed()); //false (the file should not be compressed anymore)
+var_dump($phar->extractTo(__DIR__ . "/bug79912")); //true
+var_dump(file_get_contents(__DIR__ . "/bug79912/test.txt")); //the extracted file in the folder should be decompressed
+?>
+--EXPECT--
+bool(true)
+string(60) "This is a test file.This is a test file.This is a test file."
+bool(true)
+bool(true)
+bool(false)
+bool(true)
+string(60) "This is a test file.This is a test file.This is a test file."
+--CLEAN--
+<?php
+@unlink(__DIR__ . "/bug79912/test.txt");
+@rmdir(__DIR__ . "/bug79912");
+@unlink(__DIR__ . "/bug79912.phar");
+?>