]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Fix issue 271; Handle the central directory including a zip comment.
authorMichihiro NAKAJIMA <ggcueroad@gmail.com>
Tue, 6 Nov 2012 11:20:38 +0000 (20:20 +0900)
committerMichihiro NAKAJIMA <ggcueroad@gmail.com>
Tue, 6 Nov 2012 11:20:38 +0000 (20:20 +0900)
Makefile.am
libarchive/archive_read_support_format_zip.c
libarchive/test/CMakeLists.txt
libarchive/test/test_read_format_zip_comment_stored.c [new file with mode: 0644]
libarchive/test/test_read_format_zip_comment_stored_1.zip.uu [new file with mode: 0644]
libarchive/test/test_read_format_zip_comment_stored_2.zip.uu [new file with mode: 0644]

index c81baaf455bbeb90aaf323f6b6451f26f7248a93..3fd14cfa38d683fc1bb1e24f8fb5aaf5929a1b94 100644 (file)
@@ -402,6 +402,7 @@ libarchive_test_SOURCES=                                    \
        libarchive/test/test_read_format_ustar_filename.c       \
        libarchive/test/test_read_format_xar.c                  \
        libarchive/test/test_read_format_zip.c                  \
+       libarchive/test/test_read_format_zip_comment_stored.c   \
        libarchive/test/test_read_format_zip_filename.c         \
        libarchive/test/test_read_large.c                       \
        libarchive/test/test_read_pax_truncated.c               \
@@ -633,6 +634,8 @@ libarchive_test_EXTRA_DIST=\
        libarchive/test/test_read_format_ustar_filename_eucjp.tar.Z.uu  \
        libarchive/test/test_read_format_ustar_filename_koi8r.tar.Z.uu  \
        libarchive/test/test_read_format_zip.zip.uu                     \
+       libarchive/test/test_read_format_zip_comment_stored_1.zip.uu    \
+       libarchive/test/test_read_format_zip_comment_stored_2.zip.uu    \
        libarchive/test/test_read_format_zip_filename_cp866.zip.uu      \
        libarchive/test/test_read_format_zip_filename_cp932.zip.uu      \
        libarchive/test/test_read_format_zip_filename_koi8r.zip.uu      \
index b55f1213e07e34832dab01add27c818c75c7c680..db4f781eba2093c4e381eee4a6f6d35c17656a95 100644 (file)
@@ -257,8 +257,49 @@ archive_read_format_zip_seekable_bid(struct archive_read *a, int best_bid)
        /* First four bytes are signature for end of central directory
           record.  Four zero bytes ensure this isn't a multi-volume
           Zip file (which we don't yet support). */
-       if (memcmp(p, "PK\005\006\000\000\000\000", 8) != 0)
-               return 0;
+       if (memcmp(p, "PK\005\006\000\000\000\000", 8) != 0) {
+               int64_t i, tail;
+               int found;
+
+               /*
+                * If there is a comment in the end of central directory
+                * record, 22 bytes are too short. we have to read more
+                * to properly detect the end of central directory record.
+                * Hopefully, a length of the comment is not longer than
+                * 1002 bytes. should we read more?
+                */
+               if (filesize + 22 > 1024) {
+                       tail = 1024;
+                       filesize = __archive_read_seek(a, tail * -1, SEEK_END);
+               } else {
+                       tail = filesize + 22;
+                       filesize = __archive_read_seek(a, 0, SEEK_SET);
+               }
+               if (filesize < 0)
+                       return 0;
+               if ((p = __archive_read_ahead(a, tail, NULL)) == NULL)
+                       return 0;
+               for (found = 0, i = 0;!found && i < tail - 22;) {
+                       switch (p[i]) {
+                       case 'P':
+                               if (memcmp(p+i,
+                                   "PK\005\006\000\000\000\000", 8) == 0) {
+                                       p += i;
+                                       filesize += tail -
+                                           (22 + archive_le16dec(p+20));
+                                       found = 1;
+                               } else
+                                       i += 8;
+                               break;
+                       case 'K': i += 7; break;
+                       case 005: i += 6; break;
+                       case 006: i += 5; break;
+                       default: i += 1; break;
+                       }
+               }
+               if (!found)
+                       return 0;
+       }
 
        /* Since we've already done the hard work of finding the
           end of central directory record, let's save the important
index a55a8842a20dad4f19a9ba36e026875df6dbf6e9..e39b8c13cc9d78fd339967994220c6aa53e15c5e 100644 (file)
@@ -137,6 +137,7 @@ IF(ENABLE_TEST)
     test_read_format_ustar_filename.c
     test_read_format_xar.c
     test_read_format_zip.c
+    test_read_format_zip_comment_stored.c
     test_read_format_zip_filename.c
     test_read_large.c
     test_read_pax_truncated.c
diff --git a/libarchive/test/test_read_format_zip_comment_stored.c b/libarchive/test/test_read_format_zip_comment_stored.c
new file mode 100644 (file)
index 0000000..5394ceb
--- /dev/null
@@ -0,0 +1,66 @@
+/*-
+ * Copyright (c) 2012 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+/*
+ * Read a zip file that has a zip comment in the end of the central
+ * directory record.
+ */
+static void
+verify(const char *refname)
+{
+       char *p;
+       size_t s;
+       struct archive *a;
+       struct archive_entry *ae;
+
+       extract_reference_file(refname);
+       p = slurpfile(&s, refname);
+
+       /* Symlinks can only be extracted with the seeking reader. */
+       assert((a = archive_read_new()) != NULL);
+       assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
+       assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, p, s, 1));
+
+       assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+       assertEqualString("file0", archive_entry_pathname(ae));
+       assertEqualInt(AE_IFREG | 0644, archive_entry_mode(ae));
+
+       assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+       assertEqualString("build.sh", archive_entry_pathname(ae));
+       assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae));
+       assertEqualInt(23, archive_entry_size(ae));
+
+       assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+       assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+       assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
+}
+
+DEFINE_TEST(test_read_format_zip_comment_stored)
+{
+       verify("test_read_format_zip_comment_stored_1.zip");
+       verify("test_read_format_zip_comment_stored_2.zip");
+}
diff --git a/libarchive/test/test_read_format_zip_comment_stored_1.zip.uu b/libarchive/test/test_read_format_zip_comment_stored_1.zip.uu
new file mode 100644 (file)
index 0000000..9b6449e
--- /dev/null
@@ -0,0 +1,12 @@
+begin 644 test_read_format_zip_comment_stored_1.zip
+M4$L#!`H``````.&`9D$````````````````%`!P`9FEL93!55`D``Q:WF%`6
+MMYA0=7@+``$$]0$```04````4$L#!`H``````+Q[9D'J6.I]%P```!<````(
+M`!P`8G5I;&0N<VA55`D``V.NF%!SMIA0=7@+``$$]0$```04````(R$O8FEN
+M+W-H"F5C:&\@(G1E<W0N(@I02P$"'@,*``````#A@&9!````````````````
+M!0`8````````````I($`````9FEL93!55`4``Q:WF%!U>`L``03U`0``!!0`
+M``!02P$"'@,*``````"\>V9!ZECJ?1<````7````"``8```````!````[8$_
+M````8G5I;&0N<VA55`4``V.NF%!U>`L``03U`0``!!0```!02P4&``````(`
+M`@"9````F````"0`5&AI<R!I<R!A('-A;7!L92!F:6QE(&9O<B!I<W-U92`R
+#-S$N
+`
+end
diff --git a/libarchive/test/test_read_format_zip_comment_stored_2.zip.uu b/libarchive/test/test_read_format_zip_comment_stored_2.zip.uu
new file mode 100644 (file)
index 0000000..3467bb9
--- /dev/null
@@ -0,0 +1,71 @@
+begin 644 test_read_format_zip_comment_stored_2.zip
+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
+'=64@,C<Q+@``
+`
+end