]> granicus.if.org Git - php/commitdiff
Fixed bug 64343
authorMichael Wallner <mike@php.net>
Mon, 30 Mar 2015 11:09:32 +0000 (13:09 +0200)
committerMichael Wallner <mike@php.net>
Mon, 30 Mar 2015 11:11:06 +0000 (13:11 +0200)
PharData::extractTo fails for tarball created by BSD tar

Phar did not know about PAX style global/file headers.
Skip them, to be able to read the contents of those archives.

NEWS
ext/phar/phar_internal.h
ext/phar/tar.c
ext/phar/tests/tar/bug64343.phpt [new file with mode: 0644]
ext/phar/tests/tar/files/bug64343.tar [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 5cda6a28147c977a9b053acd5f205b3042e19a0b..1cbaff8f023f8a8c83b0c39a4aaa86a57060b1a2 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -39,6 +39,10 @@ PHP                                                                        NEWS
   . Fixed bug #67403 (Add signatureType to openssl_x509_parse).
   . Add a check for RAND_egd to allow compiling against LibreSSL (Leigh)
 
+- Phar:
+  . Fixed bug 64343 (PharData::extractTo fails for tarball created by BSD tar).
+    (Mike)
+
 - Postgres:
   . Fixed bug #68741 (Null pointer dereference) (CVE-2015-1352). (Laruence)
 
index 989e6346f7f7bf382105f50209b804d1aeb07981..c862c49dcac4ee2d40c7433bfcf82a5f990304e0 100644 (file)
 #define TAR_SYMLINK '2'
 #define TAR_DIR     '5'
 #define TAR_NEW     '8'
+#define TAR_GLOBAL_HDR 'g'
+#define TAR_FILE_HDR   'x'
 
 #define PHAR_MUNG_PHP_SELF                     (1<<0)
 #define PHAR_MUNG_REQUEST_URI          (1<<1)
index 56b2a0eedf40895109deb72c5708b995c5204dee..844c6b54198821edc76b6b188824ffcf06994d7c 100644 (file)
@@ -255,6 +255,12 @@ int phar_parse_tarfile(php_stream* fp, char *fname, int fname_len, char *alias,
                size = entry.uncompressed_filesize = entry.compressed_filesize =
                        phar_tar_number(hdr->size, sizeof(hdr->size));
 
+               /* skip global/file headers (pax) */
+               if (!old && (hdr->typeflag == TAR_GLOBAL_HDR || hdr->typeflag == TAR_FILE_HDR)) {
+                       size = (size+511)&~511;
+                       goto next;
+               }
+
                if (((!old && hdr->prefix[0] == 0) || old) && strlen(hdr->name) == sizeof(".phar/signature.bin")-1 && !strncmp(hdr->name, ".phar/signature.bin", sizeof(".phar/signature.bin")-1)) {
                        off_t curloc;
 
@@ -548,6 +554,7 @@ bail:
                size = (size+511)&~511;
 
                if (((hdr->typeflag == '\0') || (hdr->typeflag == TAR_FILE)) && size > 0) {
+next:
                        /* this is not good enough - seek succeeds even on truncated tars */
                        php_stream_seek(fp, size, SEEK_CUR);
                        if ((uint)php_stream_tell(fp) > totalsize) {
diff --git a/ext/phar/tests/tar/bug64343.phpt b/ext/phar/tests/tar/bug64343.phpt
new file mode 100644 (file)
index 0000000..ed4501d
--- /dev/null
@@ -0,0 +1,16 @@
+--TEST--
+Bug #64343 (phar cannot open tars with pax headers)
+--SKIPIF--
+<?php if (!extension_loaded("phar")) die("skip"); ?>
+--FILE--
+<?php
+
+echo "Test\n";
+
+$phar = new PharData(__DIR__."/files/bug64343.tar");
+
+?>
+===DONE===
+--EXPECT--
+Test
+===DONE===
diff --git a/ext/phar/tests/tar/files/bug64343.tar b/ext/phar/tests/tar/files/bug64343.tar
new file mode 100644 (file)
index 0000000..2eeb206
Binary files /dev/null and b/ext/phar/tests/tar/files/bug64343.tar differ