summaryrefslogtreecommitdiffstats
path: root/lib/libarchive/archive_read_support_format_zip.c
diff options
context:
space:
mode:
authorkientzle <kientzle@FreeBSD.org>2008-01-15 16:27:15 +0000
committerkientzle <kientzle@FreeBSD.org>2008-01-15 16:27:15 +0000
commitb00d558d00d204771598eb590cfcf983657e0b1a (patch)
treee1e745b7e53e96efa2893e5d6a73bed04bb98e1b /lib/libarchive/archive_read_support_format_zip.c
parentc02890da0b4e1279b29fcf72906c76e4824c6037 (diff)
downloadFreeBSD-src-b00d558d00d204771598eb590cfcf983657e0b1a.zip
FreeBSD-src-b00d558d00d204771598eb590cfcf983657e0b1a.tar.gz
Handle Zip archives that are "multi-part archives with only
one part" by simply ignoring the marker at the beginning of the file. (Zip archivers reserve four bytes at the beginning of each part of a multi-part archive, if it happens to only require one part, those four bytes get filled with a placeholder that can be ignored.) Thanks to: Marius Nuennerich, for pointing me to a Zip archive that libarchive couldn't handle MFC after: 7 days
Diffstat (limited to 'lib/libarchive/archive_read_support_format_zip.c')
-rw-r--r--lib/libarchive/archive_read_support_format_zip.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/lib/libarchive/archive_read_support_format_zip.c b/lib/libarchive/archive_read_support_format_zip.c
index 24a689c..d96bea6 100644
--- a/lib/libarchive/archive_read_support_format_zip.c
+++ b/lib/libarchive/archive_read_support_format_zip.c
@@ -180,7 +180,8 @@ archive_read_format_zip_bid(struct archive_read *a)
if ((p[2] == '\001' && p[3] == '\002')
|| (p[2] == '\003' && p[3] == '\004')
|| (p[2] == '\005' && p[3] == '\006')
- || (p[2] == '\007' && p[3] == '\010'))
+ || (p[2] == '\007' && p[3] == '\010')
+ || (p[2] == '0' && p[3] == '0'))
return (30);
}
return (0);
@@ -214,6 +215,23 @@ archive_read_format_zip_read_header(struct archive_read *a,
return (ARCHIVE_FATAL);
}
+ /*
+ * "PK00" signature is used for "split" archives that
+ * only have a single segment. This means we can just
+ * skip the PK00; the first real file header should follow.
+ */
+ if (signature[2] == '0' && signature[3] == '0') {
+ (a->decompressor->consume)(a, 4);
+ if ((h = __archive_read_ahead(a, 4)) == NULL)
+ return (ARCHIVE_FATAL);
+ signature = (const char *)h;
+ if (signature[0] != 'P' || signature[1] != 'K') {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Bad ZIP file");
+ return (ARCHIVE_FATAL);
+ }
+ }
+
if (signature[2] == '\001' && signature[3] == '\002') {
/* Beginning of central directory. */
return (ARCHIVE_EOF);
OpenPOWER on IntegriCloud