]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Issue 226: Fix infinite loop when a data descriptor marking
authorTim Kientzle <kientzle@gmail.com>
Tue, 24 Jan 2012 06:05:46 +0000 (01:05 -0500)
committerTim Kientzle <kientzle@gmail.com>
Tue, 24 Jan 2012 06:05:46 +0000 (01:05 -0500)
the end of an uncompressed entry falls exactly at the end of
a block and the seeking Zip reader tries to skip it.

To test this, the test_compat_zip_7 test reads a small sample
XPS file with every block size from 1 byte up to 1000 bytes.
(For this specific bug, an 807-byte block triggers the
problem.)

SVN-Revision: 4201

libarchive/archive_read_support_format_zip.c
libarchive/test/test_compat_zip.c

index 1047e8cc87bb308c9bea687dde227163347cd5de..2201ef74e78ba1ee2ac18a34d1103088fdc3b1d2 100644 (file)
@@ -1172,7 +1172,7 @@ archive_read_format_zip_read_data_skip(struct archive_read *a)
                                return (ARCHIVE_FATAL);
                        }
                        p = buff;
-                       while (p < buff + bytes_avail - 16) {
+                       while (p <= buff + bytes_avail - 16) {
                                if (p[3] == 'P') { p += 3; }
                                else if (p[3] == 'K') { p += 2; }
                                else if (p[3] == '\007') { p += 1; }
index 4c3017cc357a419368c30125290736ae75c09702..ece62251a87245ea809299ce4f6c1986f72048ff 100644 (file)
@@ -412,19 +412,27 @@ test_compat_zip_7(void)
        struct archive_entry *ae;
        void *p;
        size_t s;
+       int i;
 
        extract_reference_file(refname);
        p = slurpfile(&s, refname);
 
-       assert((a = archive_read_new()) != NULL);
-       assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
-       assertEqualIntA(a, ARCHIVE_OK, read_open_memory_minimal(a, p, s, 16));
-
-       assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
-       assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
-       assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
-
-       assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
+       for (i = 1; i < 1000; ++i) {
+               assert((a = archive_read_new()) != NULL);
+               assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
+               assertEqualIntA(a, ARCHIVE_OK, read_open_memory_minimal(a, p, s, i));
+
+               assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+               assertEqualIntA(a, ARCHIVE_OK, archive_read_data_skip(a));
+               assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+               assertEqualIntA(a, ARCHIVE_OK, archive_read_data_skip(a));
+               assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+               assertEqualIntA(a, ARCHIVE_OK, archive_read_data_skip(a));
+               assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+               assertEqualIntA(a, ARCHIVE_OK, archive_read_data_skip(a));
+
+               assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
+       }
        free(p);
 }