merge
diff --git a/NEWS b/NEWS index 1ac8ea9..05962a0 100644 --- a/NEWS +++ b/NEWS
@@ -1,3 +1,7 @@ +X.X [201X/XX/XX] + +* Improve support for 3MF files + 1.1.1 [2016/02/07] * Build fixes for Linux
diff --git a/THANKS b/THANKS index 7a65068..10b237a 100644 --- a/THANKS +++ b/THANKS
@@ -50,6 +50,7 @@ Timo Warns <warns@pre-sense.de> Tom Callaway <tcallawa@redhat.com> Tomas Hoger <thoger@redhat.com> +Torsten Paul <Torsten.Paul@gmx.de> Vassili Courzakis <vcoxvco@googlemail.com> Wojciech Michalski <wmichalski@quay.pl> Wolfgang Glunz <Wolfgang.Glunz@gmx.de>
diff --git a/lib/zip_open.c b/lib/zip_open.c index 3f866a9..d6209ee 100644 --- a/lib/zip_open.c +++ b/lib/zip_open.c
@@ -293,11 +293,6 @@ return NULL; } - if (_zip_buffer_get_32(buffer) != 0) { - zip_error_set(error, ZIP_ER_MULTIDISK, 0); - return NULL; - } - if (eocd_offset >= EOCD64LOCLEN && memcmp(_zip_buffer_data(buffer) + eocd_offset - EOCD64LOCLEN, EOCD64LOC_MAGIC, 4) == 0) { _zip_buffer_set_offset(buffer, eocd_offset - EOCD64LOCLEN); cd = _zip_read_eocd64(za->src, buffer, buf_offset, za->flags, error); @@ -668,7 +663,8 @@ } -static zip_cdir_t *_zip_read_eocd(zip_buffer_t *buffer, zip_uint64_t buf_offset, unsigned int flags, zip_error_t *error) +static zip_cdir_t * +_zip_read_eocd(zip_buffer_t *buffer, zip_uint64_t buf_offset, unsigned int flags, zip_error_t *error) { zip_cdir_t *cd; zip_uint64_t i, nentry, size, offset, eocd_offset; @@ -680,7 +676,12 @@ eocd_offset = _zip_buffer_offset(buffer); - _zip_buffer_get(buffer, 8); /* magic and number of disks already verified */ + _zip_buffer_get(buffer, 4); /* magic already verified */ + + if (_zip_buffer_get_32(buffer) != 0) { + zip_error_set(error, ZIP_ER_MULTIDISK, 0); + return NULL; + } /* number of cdir-entries on this disk */ i = _zip_buffer_get_16(buffer); @@ -730,10 +731,14 @@ zip_uint64_t eocd_offset; zip_uint64_t size, nentry, i, eocdloc_offset; bool free_buffer; + zip_uint32_t num_disks, num_disks64, eocd_disk, eocd_disk64; eocdloc_offset = _zip_buffer_offset(buffer); - _zip_buffer_get(buffer, 8); /* magic and single disk already verified */ + _zip_buffer_get(buffer, 4); /* magic already verified */ + + num_disks = _zip_buffer_get_16(buffer); + eocd_disk = _zip_buffer_get_16(buffer); eocd_offset = _zip_buffer_get_64(buffer); if (eocd_offset > ZIP_INT64_MAX || eocd_offset + EOCD64LEN < eocd_offset) { @@ -779,8 +784,29 @@ return NULL; } - _zip_buffer_get(buffer, 12); /* skip version made by/needed and num disks */ - + _zip_buffer_get(buffer, 4); /* skip version made by/needed */ + + num_disks64 = _zip_buffer_get_32(buffer); + eocd_disk64 = _zip_buffer_get_32(buffer); + + /* if eocd values are 0xffff, we have to use eocd64 values. + otherwise, if the values are not the same, it's inconsistent; + in any case, if the value is not 0, we don't support it */ + if (num_disks == 0xffff) { + num_disks = num_disks64; + } + if (eocd_disk == 0xffff) { + eocd_disk = eocd_disk64; + } + if ((flags & ZIP_CHECKCONS) && (eocd_disk != eocd_disk64 || num_disks != num_disks64)) { + zip_error_set(error, ZIP_ER_INCONS, 0); + return NULL; + } + if (num_disks != 0 || eocd_disk != 0) { + zip_error_set(error, ZIP_ER_MULTIDISK, 0); + return NULL; + } + nentry = _zip_buffer_get_64(buffer); i = _zip_buffer_get_64(buffer);
diff --git a/regress/CMakeLists.txt b/regress/CMakeLists.txt index 8d7816e..332530f 100644 --- a/regress/CMakeLists.txt +++ b/regress/CMakeLists.txt
@@ -72,6 +72,7 @@ open_filename_empty.test open_incons.test open_many_ok.test + open_multidisk.test open_new_but_exists.test open_new_ok.test open_nonarchive.test @@ -79,6 +80,7 @@ open_ok.test open_too_short.test open_truncate.test + open_zip64_3mf.test open_zip64_ok.test rename_ascii.test rename_cp437.test
diff --git a/regress/Makefile.am b/regress/Makefile.am index 065e15e..0fb4c06 100644 --- a/regress/Makefile.am +++ b/regress/Makefile.am
@@ -86,6 +86,7 @@ incons-local-size-larger.zip \ large-uncompressable \ manyfiles-zip.zip \ + multidisk.zip \ rename_ok.zip \ streamed.zip \ streamed-zip64.zip \ @@ -119,7 +120,8 @@ utf-8-standardization-input.zip \ utf-8-standardization-output.zip \ zip-in-archive-comment.zip \ - zip64.zip + zip64.zip \ + zip64-3mf.zip TESTS_ENVIRONMENT= ZIPCMP=${top_builddir}/src/zipcmp # ${srcdir}/runtest @@ -186,6 +188,7 @@ open_filename_empty.test \ open_incons.test \ open_many_ok.test \ + open_multidisk.test \ open_new_but_exists.test \ open_new_ok.test \ open_nonarchive.test \ @@ -193,6 +196,7 @@ open_ok.test \ open_too_short.test \ open_truncate.test \ + open_zip64_3mf.test \ open_zip64_ok.test \ rename_ascii.test \ rename_cp437.test \
diff --git a/regress/multidisk.zip b/regress/multidisk.zip new file mode 100644 index 0000000..28dafb9 --- /dev/null +++ b/regress/multidisk.zip Binary files differ
diff --git a/regress/open_multidisk.test b/regress/open_multidisk.test new file mode 100644 index 0000000..1da4a5c --- /dev/null +++ b/regress/open_multidisk.test
@@ -0,0 +1,7 @@ +# zip_open: file is part of a multi-disk zip archive +program tryopen +args test.piz +return 1 +file test.piz multidisk.zip multidisk.zip +stdout opening 'test.piz' returned error 1 +stderr 1 errors
diff --git a/regress/open_zip64_3mf.test b/regress/open_zip64_3mf.test new file mode 100644 index 0000000..4a57154 --- /dev/null +++ b/regress/open_zip64_3mf.test
@@ -0,0 +1,6 @@ +# zip_open: ZIP64 file opens fine even when most eocd entries are 0xff (3MF format) +program tryopen +args test.zip +return 0 +file test.zip zip64-3mf.zip zip64-3mf.zip +stdout opening 'test.zip' succeeded, 1 entries
diff --git a/regress/zip64-3mf.zip b/regress/zip64-3mf.zip new file mode 100644 index 0000000..a2ccf24 --- /dev/null +++ b/regress/zip64-3mf.zip Binary files differ