Improve support for 3MF files.

Some of these set lots of data in the EOCD to 0xff, relying
on the EOCD64 data.

Add two test cases, one for this, and one for multidisk support
(which doesn't exist in libzip).
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