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