From: Tim Kientzle Date: Tue, 24 Jan 2012 06:05:46 +0000 (-0500) Subject: Issue 226: Fix infinite loop when a data descriptor marking X-Git-Tag: v3.0.4~2^2~153 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=da64ed4917ae4ff88c1f9bdf22eee62768350fab;p=thirdparty%2Flibarchive.git Issue 226: Fix infinite loop when a data descriptor marking 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 --- diff --git a/libarchive/archive_read_support_format_zip.c b/libarchive/archive_read_support_format_zip.c index 1047e8cc8..2201ef74e 100644 --- a/libarchive/archive_read_support_format_zip.c +++ b/libarchive/archive_read_support_format_zip.c @@ -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; } diff --git a/libarchive/test/test_compat_zip.c b/libarchive/test/test_compat_zip.c index 4c3017cc3..ece62251a 100644 --- a/libarchive/test/test_compat_zip.c +++ b/libarchive/test/test_compat_zip.c @@ -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); }