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
This commit is contained in:
Tim Kientzle committed 2012-01-24 01:05:46 -05:00
1 parent 8a2f59974b
commit da64ed4917
2 files changed
+16 -8

No files matched your search

+1 -1
View 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; }
+15 -7
View 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));
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_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_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));
assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
}
free(p);
}