summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristoph M. Becker <cmbecker69@gmx.de>2020-12-02 14:49:43 +0100
committerChristoph M. Becker <cmbecker69@gmx.de>2020-12-04 13:02:29 +0100
commit8588ae72156eeead928a8fe93bb8a5ab293f1e89 (patch)
tree54144ab47f21410d3ac86b19d52ce638661ffaab
parent8f8e6f95af219bc2e10d52c34016bc993c8419ef (diff)
downloadphp-git-8588ae72156eeead928a8fe93bb8a5ab293f1e89.tar.gz
Fix #75102: `PharData` says invalid checksum for valid tar
Apparently, there are broken tarballs out there which are actually in ustar format, but did not write the `ustar` marker. Since popular tar tools like GNU tar and 7zip have no issues dealing with such tarballs, Phar should also be more resilient. Thus, when the first checksum check of a tarball in (presumed) in old- style format fails, we check whether the checksum would be suitable for ustar format; if so, we treat the tarball as being in ustar format. Closes GH-6479.
-rw-r--r--NEWS1
-rw-r--r--ext/phar/tar.c9
-rw-r--r--ext/phar/tests/bug75102.phpt13
-rw-r--r--ext/phar/tests/bug75102.tarbin0 -> 2048 bytes
4 files changed, 23 insertions, 0 deletions
diff --git a/NEWS b/NEWS
index 56eed2700a..c7fe41fd88 100644
--- a/NEWS
+++ b/NEWS
@@ -26,6 +26,7 @@ PHP NEWS
- Phar:
. Fixed bug #73809 (Phar Zip parse crash - mmap fail). (cmb)
+ . Fixed #75102 (`PharData` says invalid checksum for valid tar). (cmb)
- Phpdbg:
. Fixed bug #76813 (Access violation near NULL on source operand). (cmb)
diff --git a/ext/phar/tar.c b/ext/phar/tar.c
index 773bdbca70..03e6dd4ff4 100644
--- a/ext/phar/tar.c
+++ b/ext/phar/tar.c
@@ -271,6 +271,15 @@ int phar_parse_tarfile(php_stream* fp, char *fname, size_t fname_len, char *alia
memset(hdr->checksum, ' ', sizeof(hdr->checksum));
sum2 = phar_tar_checksum(buf, old?sizeof(old_tar_header):sizeof(tar_header));
+ if (old && sum2 != sum1) {
+ uint32_t sum3 = phar_tar_checksum(buf, sizeof(tar_header));
+ if (sum3 == sum1) {
+ /* apparently a broken tar which is in ustar format w/o setting the ustar marker */
+ sum2 = sum3;
+ old = 0;
+ }
+ }
+
size = entry.uncompressed_filesize = entry.compressed_filesize =
phar_tar_number(hdr->size, sizeof(hdr->size));
diff --git a/ext/phar/tests/bug75102.phpt b/ext/phar/tests/bug75102.phpt
new file mode 100644
index 0000000000..9ed133c09d
--- /dev/null
+++ b/ext/phar/tests/bug75102.phpt
@@ -0,0 +1,13 @@
+--TEST--
+Bug #75102 (`PharData` says invalid checksum for valid tar)
+--SKIPIF--
+<?php
+if (!extension_loaded('phar')) die('skip phar extension not available');
+?>
+--FILE--
+<?php
+$phar = new PharData(__DIR__ . '/bug75102.tar');
+var_dump(file_get_contents($phar['test.txt']->getPathName()));
+?>
+--EXPECT--
+string(9) "yada yada"
diff --git a/ext/phar/tests/bug75102.tar b/ext/phar/tests/bug75102.tar
new file mode 100644
index 0000000000..532cc3299b
--- /dev/null
+++ b/ext/phar/tests/bug75102.tar
Binary files differ