Improve inconsistency detail reporting.
diff --git a/developer-xcode/libzip.xcodeproj/project.pbxproj b/developer-xcode/libzip.xcodeproj/project.pbxproj
index a4c2ed6..41dfdf5 100644
--- a/developer-xcode/libzip.xcodeproj/project.pbxproj
+++ b/developer-xcode/libzip.xcodeproj/project.pbxproj
@@ -164,6 +164,8 @@
 		4B0454BA1E8E3E08002FA1F9 /* zip_source_compress.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B0454B61E8E3DF7002FA1F9 /* zip_source_compress.c */; };
 		4B0454BC1E8E3E24002FA1F9 /* zip_algorithm_bzip2.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B0454B41E8E3DF7002FA1F9 /* zip_algorithm_bzip2.c */; };
 		4B0454BD1E8E3E24002FA1F9 /* zip_algorithm_deflate.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B0454B51E8E3DF7002FA1F9 /* zip_algorithm_deflate.c */; };
+		4B30B50225F11684002CE070 /* zip_algorithm_zstd.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B9E577A24C7026B00CEE0D6 /* zip_algorithm_zstd.c */; };
+		4B30B53425F117C4002CE070 /* libzstd.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B30B53325F117C4002CE070 /* libzstd.dylib */; };
 		4B3A5F521DF96EB4005A53A1 /* zip_fseek.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B3A5F4D1DF96D83005A53A1 /* zip_fseek.c */; };
 		4B3A5F531DF96EB4005A53A1 /* zip_ftell.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B3A5F4E1DF96D83005A53A1 /* zip_ftell.c */; };
 		4B3FAE802385C5CC00192D6A /* zip_algorithm_xz.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B3FAE7F2385C5A300192D6A /* zip_algorithm_xz.c */; };
@@ -187,8 +189,6 @@
 		4B93995E24631B3E00AEBDA4 /* zip_source_file.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B93995924631B3E00AEBDA4 /* zip_source_file.h */; };
 		4B972050188EBE85002FAFAD /* zip_file_get_external_attributes.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B97204D188EBE85002FAFAD /* zip_file_get_external_attributes.c */; };
 		4B972052188EBE85002FAFAD /* zip_file_set_external_attributes.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B97204E188EBE85002FAFAD /* zip_file_set_external_attributes.c */; };
-		4B9E577C24C7202000CEE0D6 /* zip_algorithm_zstd.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B9E577A24C7026B00CEE0D6 /* zip_algorithm_zstd.c */; };
-		4B9E578824C9770C00CEE0D6 /* libzstd.1.4.5.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B9E578724C9770C00CEE0D6 /* libzstd.1.4.5.dylib */; };
 		4B9E578A24C9779900CEE0D6 /* zip_err_str.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B9E578924C9779900CEE0D6 /* zip_err_str.c */; };
 		4BACD59315BC2CFA00920691 /* libzip.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B01D68B15B2F3F1002D5007 /* libzip.framework */; };
 		4BACD59415BC2D0800920691 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B01D70815B2F4CF002D5007 /* libz.dylib */; };
@@ -607,6 +607,7 @@
 		4B30B4BF25F0ECC8002CE070 /* liboverride.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = liboverride.c; sourceTree = "<group>"; };
 		4B30B4D025F0ECF7002CE070 /* fuzz_main.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = fuzz_main.c; sourceTree = "<group>"; };
 		4B30B4D125F0EE6D002CE070 /* liboverride-test.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = "liboverride-test.c"; sourceTree = "<group>"; };
+		4B30B53325F117C4002CE070 /* libzstd.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libzstd.dylib; path = /usr/local/lib/libzstd.dylib; sourceTree = "<group>"; };
 		4B3A5F4D1DF96D83005A53A1 /* zip_fseek.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = zip_fseek.c; sourceTree = "<group>"; };
 		4B3A5F4E1DF96D83005A53A1 /* zip_ftell.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = zip_ftell.c; sourceTree = "<group>"; };
 		4B3FAE7F2385C5A300192D6A /* zip_algorithm_xz.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = zip_algorithm_xz.c; sourceTree = "<group>"; };
@@ -955,7 +956,7 @@
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
-				4B9E578824C9770C00CEE0D6 /* libzstd.1.4.5.dylib in Frameworks */,
+				4B30B53425F117C4002CE070 /* libzstd.dylib in Frameworks */,
 				4BE92AA720345E3800509BC8 /* libbz2.tbd in Frameworks */,
 				4B01D73C15B2F6AF002D5007 /* libz.dylib in Frameworks */,
 				4B3FAE822385C79200192D6A /* liblzma.5.dylib in Frameworks */,
@@ -1405,6 +1406,7 @@
 		4BDC71CA15B181DA00236D3C /* Frameworks */ = {
 			isa = PBXGroup;
 			children = (
+				4B30B53325F117C4002CE070 /* libzstd.dylib */,
 				4B9E578724C9770C00CEE0D6 /* libzstd.1.4.5.dylib */,
 				4B3FAE812385C79200192D6A /* liblzma.5.dylib */,
 				4BE92AA820345E5500509BC8 /* libnettle.6.dylib */,
@@ -1820,7 +1822,7 @@
 		4BDC71BF15B181DA00236D3C /* Project object */ = {
 			isa = PBXProject;
 			attributes = {
-				LastUpgradeCheck = 1140;
+				LastUpgradeCheck = 1240;
 				ORGANIZATIONNAME = NiH;
 				TargetAttributes = {
 					3D7E35361B3305FB00022624 = {
@@ -1924,6 +1926,7 @@
 				3D7E35491B330AD500022624 /* zip_source_is_deleted.c in Sources */,
 				4BCF3039199ABDDA0064207B /* zip_source_tell_write.c in Sources */,
 				4B01D6A615B2F46B002D5007 /* zip_add_dir.c in Sources */,
+				4B30B50225F11684002CE070 /* zip_algorithm_zstd.c in Sources */,
 				4B972052188EBE85002FAFAD /* zip_file_set_external_attributes.c in Sources */,
 				4B0454BA1E8E3E08002FA1F9 /* zip_source_compress.c in Sources */,
 				4B3FAE802385C5CC00192D6A /* zip_algorithm_xz.c in Sources */,
@@ -1994,7 +1997,6 @@
 				4B01D6D015B2F46B002D5007 /* zip_get_num_files.c in Sources */,
 				4B01D6D115B2F46B002D5007 /* zip_memdup.c in Sources */,
 				4B01D6D215B2F46B002D5007 /* zip_name_locate.c in Sources */,
-				4B9E577C24C7202000CEE0D6 /* zip_algorithm_zstd.c in Sources */,
 				4B01D6D315B2F46B002D5007 /* zip_new.c in Sources */,
 				4B01D6D415B2F46B002D5007 /* zip_open.c in Sources */,
 				4B01D6D515B2F46B002D5007 /* zip_rename.c in Sources */,
@@ -2292,10 +2294,7 @@
 				GCC_WARN_SIGN_COMPARE = YES;
 				INFOPLIST_FILE = Info.plist;
 				INSTALL_PATH = "@rpath";
-				LIBRARY_SEARCH_PATHS = (
-					"$(inherited)",
-					/usr/local/Cellar/zstd/1.4.5/lib,
-				);
+				LIBRARY_SEARCH_PATHS = /usr/local/Cellar/zstd/1.4.9/lib;
 				PRODUCT_BUNDLE_IDENTIFIER = "at.nih.${PRODUCT_NAME:rfc1034identifier}";
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SKIP_INSTALL = YES;
@@ -2327,10 +2326,7 @@
 				GCC_WARN_SIGN_COMPARE = YES;
 				INFOPLIST_FILE = Info.plist;
 				INSTALL_PATH = "@rpath";
-				LIBRARY_SEARCH_PATHS = (
-					"$(inherited)",
-					/usr/local/Cellar/zstd/1.4.5/lib,
-				);
+				LIBRARY_SEARCH_PATHS = /usr/local/Cellar/zstd/1.4.9/lib;
 				PRODUCT_BUNDLE_IDENTIFIER = "at.nih.${PRODUCT_NAME:rfc1034identifier}";
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SKIP_INSTALL = YES;
@@ -2656,6 +2652,7 @@
 				CLANG_WARN_INFINITE_RECURSION = YES;
 				CLANG_WARN_INT_CONVERSION = YES;
 				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+				CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
 				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
 				CLANG_WARN_STRICT_PROTOTYPES = YES;
 				CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
@@ -2683,13 +2680,14 @@
 				GCC_WARN_UNUSED_FUNCTION = YES;
 				GCC_WARN_UNUSED_VARIABLE = YES;
 				HEADER_SEARCH_PATHS = (
-					/usr/local/include,
-					../lib,
 					.,
+					../lib,
 					../src,
+					/usr/local/include,
 				);
-				IPHONEOS_DEPLOYMENT_TARGET = 8.0;
-				MACOSX_DEPLOYMENT_TARGET = 10.6;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
+				LIBRARY_SEARCH_PATHS = /usr/local/lib;
+				MACOSX_DEPLOYMENT_TARGET = 11.0;
 				ONLY_ACTIVE_ARCH = YES;
 				OTHER_CFLAGS = "";
 				SDKROOT = macosx;
@@ -2716,6 +2714,7 @@
 				CLANG_WARN_INFINITE_RECURSION = YES;
 				CLANG_WARN_INT_CONVERSION = YES;
 				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+				CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
 				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
 				CLANG_WARN_STRICT_PROTOTYPES = YES;
 				CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
@@ -2739,13 +2738,14 @@
 				GCC_WARN_UNUSED_FUNCTION = YES;
 				GCC_WARN_UNUSED_VARIABLE = YES;
 				HEADER_SEARCH_PATHS = (
-					/usr/local/include,
-					../lib,
 					.,
+					../lib,
 					../src,
+					/usr/local/include,
 				);
-				IPHONEOS_DEPLOYMENT_TARGET = 8.0;
-				MACOSX_DEPLOYMENT_TARGET = 10.6;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
+				LIBRARY_SEARCH_PATHS = /usr/local/lib;
+				MACOSX_DEPLOYMENT_TARGET = 11.0;
 				OTHER_CFLAGS = "";
 				SDKROOT = macosx;
 				USE_HEADERMAP = NO;
diff --git a/developer-xcode/zip_err_str.c b/developer-xcode/zip_err_str.c
index c46258b..09440b8 100644
--- a/developer-xcode/zip_err_str.c
+++ b/developer-xcode/zip_err_str.c
@@ -1,6 +1,6 @@
 /*
   This file was generated automatically by CMake
-  from zip.h; make changes there.
+  from zip.h and zipint.h; make changes there.
 */
 
 #include "zipint.h"
@@ -43,10 +43,14 @@
 
 const int _zip_nerr_str = sizeof(_zip_err_str)/sizeof(_zip_err_str[0]);
 
+#define L ZIP_ET_LIBZIP
 #define N ZIP_ET_NONE
 #define S ZIP_ET_SYS
 #define Z ZIP_ET_ZLIB
 
+#define E true
+#define G false
+
 const int _zip_err_type[] = {
     N,
     N,
@@ -69,7 +73,7 @@
     N,
     N,
     N,
-    N,
+    L,
     S,
     N,
     N,
@@ -82,3 +86,20 @@
     N,
     N,
 };
+
+const struct _zip_err_detail _zip_err_details[] = {
+    { G, "no detail" },
+    { G, "central directory overlaps EOCD, or there is space between them" },
+    { G, "archive comment length incorrect" },
+    { G, "central directory length invalid" },
+    { E, "central header invalid" },
+    { G, "central directory count of entries is incorrect" },
+    { E, "local and central headers do not match" },
+    { G, "wrong EOCD length" },
+    { G, "EOCD64 overlaps EOCD, or there is space between them" },
+    { G, "EOCD64 magic incorrect" },
+    { G, "EOCD64 and EOCD do not match" },
+    { G, "invalid value in central directory" },
+};
+
+const int _zip_err_details_count = sizeof(_zip_err_details)/sizeof(_zip_err_details[0]);
diff --git a/lib/zip_algorithm_xz.c b/lib/zip_algorithm_xz.c
index 25abaf2..09d9f74 100644
--- a/lib/zip_algorithm_xz.c
+++ b/lib/zip_algorithm_xz.c
@@ -258,7 +258,7 @@
     /* For decompression of LZMA1: Have we read the full "lzma alone" header yet? */
     if (ctx->method == ZIP_CM_LZMA && !ctx->compress && ctx->header_state == INCOMPLETE) {
         /* if not, get more of the data */
-        zip_uint8_t got = ZIP_MIN(HEADER_BYTES_ZIP - ctx->header_bytes_offset, length);
+        zip_uint8_t got = (zip_uint8_t)ZIP_MIN(HEADER_BYTES_ZIP - ctx->header_bytes_offset, length);
         memcpy(ctx->header + ctx->header_bytes_offset, data, got);
         ctx->header_bytes_offset += got;
         length -= got;
@@ -335,7 +335,7 @@
         }
         if (ctx->header_state == OUTPUT) {
             /* write header */
-            zip_uint8_t write_len = ZIP_MIN(HEADER_BYTES_ZIP - ctx->header_bytes_offset, *length);
+            zip_uint8_t write_len = (zip_uint8_t)ZIP_MIN(HEADER_BYTES_ZIP - ctx->header_bytes_offset, *length);
             memcpy(data, ctx->header + ctx->header_bytes_offset, write_len);
             ctx->header_bytes_offset += write_len;
             *length = write_len;
diff --git a/lib/zip_dirent.c b/lib/zip_dirent.c
index 5226a6e..1cb4c98 100644
--- a/lib/zip_dirent.c
+++ b/lib/zip_dirent.c
@@ -421,7 +421,7 @@
 
     if (from_buffer) {
         if (_zip_buffer_left(buffer) < variable_size) {
-            zip_error_set(error, ZIP_ER_INCONS, 0);
+            zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_VARIABLE_SIZE_OVERFLOW);
             return -1;
         }
     }
@@ -437,7 +437,7 @@
         zde->filename = _zip_read_string(buffer, src, filename_len, 1, error);
         if (!zde->filename) {
             if (zip_error_code_zip(error) == ZIP_ER_EOF) {
-                zip_error_set(error, ZIP_ER_INCONS, 0);
+                zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_VARIABLE_SIZE_OVERFLOW);
             }
             if (!from_buffer) {
                 _zip_buffer_free(buffer);
@@ -447,7 +447,7 @@
 
         if (zde->bitflags & ZIP_GPBF_ENCODING_UTF_8) {
             if (_zip_guess_encoding(zde->filename, ZIP_ENCODING_UTF8_KNOWN) == ZIP_ENCODING_ERROR) {
-                zip_error_set(error, ZIP_ER_INCONS, 0);
+                zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_INVALID_UTF8_IN_FILENAME);
                 if (!from_buffer) {
                     _zip_buffer_free(buffer);
                 }
@@ -487,7 +487,7 @@
         }
         if (zde->bitflags & ZIP_GPBF_ENCODING_UTF_8) {
             if (_zip_guess_encoding(zde->comment, ZIP_ENCODING_UTF8_KNOWN) == ZIP_ENCODING_ERROR) {
-                zip_error_set(error, ZIP_ER_INCONS, 0);
+                zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_INVALID_UTF8_IN_COMMENT);
                 if (!from_buffer) {
                     _zip_buffer_free(buffer);
                 }
@@ -562,7 +562,7 @@
                 ok = false;
             }
             if (!ok) {
-                zip_error_set(error, ZIP_ER_INCONS, 0);
+                zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_INVALID_ZIP64_EF);
                 _zip_buffer_free(ef_buffer);
                 if (!from_buffer) {
                     _zip_buffer_free(buffer);
@@ -651,7 +651,7 @@
     ef = _zip_ef_get_by_id(de->extra_fields, &ef_len, ZIP_EF_WINZIP_AES, 0, ZIP_EF_BOTH, NULL);
 
     if (ef == NULL || ef_len < 7) {
-        zip_error_set(error, ZIP_ER_INCONS, 0);
+        zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_INVALID_WINZIPAES_EF);
         return false;
     }
 
@@ -704,7 +704,7 @@
     }
 
     if (ef_len != 7) {
-        zip_error_set(error, ZIP_ER_INCONS, 0);
+        zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_INVALID_WINZIPAES_EF);
         _zip_buffer_free(buffer);
         return false;
     }
diff --git a/lib/zip_extra_field.c b/lib/zip_extra_field.c
index 7424d88..0887397 100644
--- a/lib/zip_extra_field.c
+++ b/lib/zip_extra_field.c
@@ -219,7 +219,7 @@
         ef_data = _zip_buffer_get(buffer, flen);
 
         if (ef_data == NULL) {
-            zip_error_set(error, ZIP_ER_INCONS, 0);
+            zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_INVALID_EF_LENGTH);
             _zip_buffer_free(buffer);
             _zip_ef_free(ef_head);
             return false;
@@ -247,7 +247,7 @@
         zip_uint8_t *garbage;
         garbage = _zip_buffer_get(buffer, glen);
         if (glen >= 4 || garbage == NULL || memcmp(garbage, "\0\0\0", glen) != 0) {
-            zip_error_set(error, ZIP_ER_INCONS, 0);
+            zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_EF_TRAILING_GARBAGE);
             _zip_buffer_free(buffer);
             _zip_ef_free(ef_head);
             return false;
diff --git a/lib/zip_open.c b/lib/zip_open.c
index 1f1f1dc..58bcec3 100644
--- a/lib/zip_open.c
+++ b/lib/zip_open.c
@@ -364,8 +364,11 @@
         }
 
         if ((cd->entry[i].orig = _zip_dirent_new()) == NULL || (entry_size = _zip_dirent_read(cd->entry[i].orig, za->src, cd_buffer, false, error)) < 0) {
-            if (grown && zip_error_code_zip(error) == ZIP_ER_NOZIP) {
-                zip_error_set(error, ZIP_ER_INCONS, MAKE_DETAIL_WITH_INDEX(i, ZIP_ER_DETAIL_CDIR_ENTRY_INVALID));
+	    if (zip_error_code_zip(error) == ZIP_ER_INCONS) {
+		zip_error_set(error, ZIP_ER_INCONS, ADD_INDEX_TO_DETAIL(zip_error_code_system(error), i));
+	    }
+	    else if (grown && zip_error_code_zip(error) == ZIP_ER_NOZIP) {
+                zip_error_set(error, ZIP_ER_INCONS, MAKE_DETAIL_WITH_INDEX(ZIP_ER_DETAIL_CDIR_ENTRY_INVALID, i));
             }
             _zip_cdir_free(cd);
             _zip_buffer_free(cd_buffer);
@@ -454,6 +457,9 @@
         }
 
         if (_zip_dirent_read(&temp, za->src, NULL, true, error) == -1) {
+	    if (zip_error_code_zip(error) == ZIP_ER_INCONS) {
+		zip_error_set(error, ZIP_ER_INCONS, ADD_INDEX_TO_DETAIL(zip_error_code_system(error), i));
+	    }
             _zip_dirent_finalize(&temp);
             return -1;
         }
diff --git a/lib/zip_source_crc.c b/lib/zip_source_crc.c
index cae7363..ab38b13 100644
--- a/lib/zip_source_crc.c
+++ b/lib/zip_source_crc.c
@@ -112,7 +112,8 @@
                         return -1;
                     }
                     if ((st.valid & ZIP_STAT_SIZE) && st.size != ctx->size) {
-                        zip_error_set(&ctx->error, ZIP_ER_INCONS, 0);
+                        /* We don't have the index here, but the caller should know which file they are reading from. */
+                        zip_error_set(&ctx->error, ZIP_ER_INCONS, MAKE_DETAIL_WITH_INDEX(ZIP_ER_DETAIL_INVALID_FILE_LENGTH, MAX_DETAIL_INDEX));
                         return -1;
                     }
                 }
diff --git a/lib/zip_source_window.c b/lib/zip_source_window.c
index b63ba1d..89344e1 100644
--- a/lib/zip_source_window.c
+++ b/lib/zip_source_window.c
@@ -149,7 +149,7 @@
             }
             if (ctx->end + offset < ctx->end) {
                 /* zip archive data claims end of data past zip64 limits */
-                zip_error_set(&ctx->error, ZIP_ER_INCONS, 0);
+                zip_error_set(&ctx->error, ZIP_ER_INCONS, MAKE_DETAIL_WITH_INDEX(ZIP_ER_DETAIL_CDIR_ENTRY_INVALID, ctx->source_index));
                 return -1;
             }
             ctx->start += offset;
diff --git a/lib/zipint.h b/lib/zipint.h
index 47b48c5..df7dfa3 100644
--- a/lib/zipint.h
+++ b/lib/zipint.h
@@ -199,9 +199,11 @@
 
 /* macros for libzip-internal errors */
 #define MAX_DETAIL_INDEX 0xffffff
-#define MAKE_DETAIL_WITH_INDEX(error, index) ((((index) > MAX_DETAIL_INDEX) ? MAX_DETAIL_INDEX : (index)) << 8 | (error))
+#define MAKE_DETAIL_WITH_INDEX(error, index) ((((index) > MAX_DETAIL_INDEX) ? MAX_DETAIL_INDEX : (int)(index)) << 8 | (error))
 #define GET_INDEX_FROM_DETAIL(error) (((error) >> 8) & MAX_DETAIL_INDEX)
 #define GET_ERROR_FROM_DETAIL(error) ((error) & 0xff)
+#define ADD_INDEX_TO_DETAIL(error, index) MAKE_DETAIL_WITH_INDEX(GET_ERROR_FROM_DETAIL(error), (index))
+
 /* error code for libzip-internal errors */
 #define ZIP_ER_DETAIL_NO_DETAIL 0   /* G no detail */
 #define ZIP_ER_DETAIL_CDIR_OVERLAPS_EOCD 1  /* G central directory overlaps EOCD, or there is space between them */
@@ -215,6 +217,14 @@
 #define ZIP_ER_DETAIL_EOCD64_WRONG_MAGIC 9  /* G EOCD64 magic incorrect */
 #define ZIP_ER_DETAIL_EOCD64_MISMATCH 10  /* G EOCD64 and EOCD do not match */
 #define ZIP_ER_DETAIL_CDIR_INVALID 11  /* G invalid value in central directory */
+#define ZIP_ER_DETAIL_VARIABLE_SIZE_OVERFLOW 12 /* E variable size fields overflow header */
+#define ZIP_ER_DETAIL_INVALID_UTF8_IN_FILENAME 13 /* E invalid UTF-8 in filename */
+#define ZIP_ER_DETAIL_INVALID_UTF8_IN_COMMENT 13 /* E invalid UTF-8 in comment */
+#define ZIP_ER_DETAIL_INVALID_ZIP64_EF 14 /* E invalid Zip64 extra field */
+#define ZIP_ER_DETAIL_INVALID_WINZIPAES_EF 14 /* E invalid WinZip AES extra field */
+#define ZIP_ER_DETAIL_EF_TRAILING_GARBAGE 15 /* E garbage at end of extra fields */
+#define ZIP_ER_DETAIL_INVALID_EF_LENGTH 16 /* E extra field length is invalid */
+#define ZIP_ER_DETAIL_INVALID_FILE_LENGTH 17 /* E file length in header doesn't match actual file length */
 
 /* directory entry: general purpose bit flags */
 
diff --git a/regress/extra_field_align.test b/regress/extra_field_align.test
index fe42977..3bb51c9 100644
--- a/regress/extra_field_align.test
+++ b/regress/extra_field_align.test
@@ -17,16 +17,16 @@
 args -c extra_field_align_1-0.zzip extra_field_align_1-ff.zzip extra_field_align_2-0.zzip extra_field_align_2-ff.zzip extra_field_align_3-0.zzip extra_field_align_3-ff.zzip extra_field_align_4-ff.zzip extra_field_align_1-ef_00.zzip extra_field_align_1-ef_ff.zzip extra_field_align_2-ef_00.zzip extra_field_align_2-ef_ff.zzip extra_field_align_3-ef_00.zzip extra_field_align_3-ef_ff.zzip
 return 1
 stdout opening 'extra_field_align_1-0.zzip' succeeded, 1 entries
-stdout opening 'extra_field_align_1-ff.zzip' returned error 21
+stdout opening 'extra_field_align_1-ff.zzip' returned error 21/15
 stdout opening 'extra_field_align_2-0.zzip' succeeded, 1 entries
-stdout opening 'extra_field_align_2-ff.zzip' returned error 21
+stdout opening 'extra_field_align_2-ff.zzip' returned error 21/15
 stdout opening 'extra_field_align_3-0.zzip' succeeded, 1 entries
-stdout opening 'extra_field_align_3-ff.zzip' returned error 21
+stdout opening 'extra_field_align_3-ff.zzip' returned error 21/15
 stdout opening 'extra_field_align_4-ff.zzip' succeeded, 1 entries
 stdout opening 'extra_field_align_1-ef_00.zzip' succeeded, 1 entries
-stdout opening 'extra_field_align_1-ef_ff.zzip' returned error 21
+stdout opening 'extra_field_align_1-ef_ff.zzip' returned error 21/15
 stdout opening 'extra_field_align_2-ef_00.zzip' succeeded, 1 entries
-stdout opening 'extra_field_align_2-ef_ff.zzip' returned error 21
+stdout opening 'extra_field_align_2-ef_ff.zzip' returned error 21/15
 stdout opening 'extra_field_align_3-ef_00.zzip' succeeded, 1 entries
-stdout opening 'extra_field_align_3-ef_ff.zzip' returned error 21
+stdout opening 'extra_field_align_3-ef_ff.zzip' returned error 21/15
 stderr 6 errors
diff --git a/regress/open_cons_extrabytes.test b/regress/open_cons_extrabytes.test
index beeb90e..ab6b018 100644
--- a/regress/open_cons_extrabytes.test
+++ b/regress/open_cons_extrabytes.test
@@ -3,5 +3,5 @@
 file testextrabytes.zzip testextrabytes.zip testextrabytes.zip
 args -c testextrabytes.zzip
 return 1
-stdout opening 'testextrabytes.zzip' returned error 21
+stdout opening 'testextrabytes.zzip' returned error 21/2
 stderr 1 errors
diff --git a/regress/open_file_count.test b/regress/open_file_count.test
index 5078978..1f18deb 100644
--- a/regress/open_file_count.test
+++ b/regress/open_file_count.test
@@ -6,7 +6,7 @@
 file incons-file-count-overflow.zzip incons-file-count-overflow.zip incons-file-count-overflow.zip
 args incons-file-count-high.zzip incons-file-count-low.zzip incons-file-count-overflow.zzip
 return 1
-stdout opening 'incons-file-count-high.zzip' returned error 21
-stdout opening 'incons-file-count-low.zzip' returned error 21
-stdout opening 'incons-file-count-overflow.zzip' returned error 21
+stdout opening 'incons-file-count-high.zzip' returned error 21/5
+stdout opening 'incons-file-count-low.zzip' returned error 21/5
+stdout opening 'incons-file-count-overflow.zzip' returned error 21/11
 stderr 3 errors
diff --git a/regress/open_incons.test b/regress/open_incons.test
index cda6afb..c0e63a0 100644
--- a/regress/open_incons.test
+++ b/regress/open_incons.test
@@ -36,39 +36,39 @@
 file incons-local-size-larger.zzip incons-local-size-larger.zip incons-local-size-larger.zip
 args -c incons-archive-comment-longer.zzip incons-archive-comment-shorter.zzip incons-cdoffset.zzip incons-central-compression-method.zzip incons-central-compsize-larger-toolarge.zzip incons-central-compsize-larger.zzip incons-central-compsize-smaller.zzip incons-central-crc.zzip incons-central-date.zzip incons-central-file-comment-longer.zzip incons-central-file-comment-shorter.zzip incons-central-magic-bad.zzip incons-central-magic-bad2.zzip incons-central-size-larger.zzip incons-data.zzip incons-ef-central-size-wrong.zzip incons-ef-local-id-size.zzip incons-ef-local-id.zzip incons-ef-local-size.zzip incons-eocd-magic-bad.zzip incons-file-count-high.zzip incons-file-count-low.zzip incons-file-count-overflow.zzip incons-local-compression-method.zzip incons-local-compsize-larger.zzip incons-local-compsize-smaller.zzip incons-local-crc.zzip incons-local-filename-long.zzip incons-local-filename-missing.zzip incons-local-filename-short.zzip incons-local-filename.zzip incons-local-magic-bad.zzip incons-local-size-larger.zzip
 return 1
-stdout opening 'incons-archive-comment-longer.zzip' returned error 21
-stdout opening 'incons-archive-comment-shorter.zzip' returned error 21
-stdout opening 'incons-cdoffset.zzip' returned error 21
-stdout opening 'incons-central-compression-method.zzip' returned error 21
+stdout opening 'incons-archive-comment-longer.zzip' returned error 21/2
+stdout opening 'incons-archive-comment-shorter.zzip' returned error 21/2
+stdout opening 'incons-cdoffset.zzip' returned error 21/1
+stdout opening 'incons-central-compression-method.zzip' returned error 21/6
 stdout opening 'incons-central-compsize-larger-toolarge.zzip' returned error 19
-stdout opening 'incons-central-compsize-larger.zzip' returned error 21
-stdout opening 'incons-central-compsize-smaller.zzip' returned error 21
-stdout opening 'incons-central-crc.zzip' returned error 21
-stdout opening 'incons-central-date.zzip' returned error 21
-stdout opening 'incons-central-file-comment-longer.zzip' returned error 21
-stdout opening 'incons-central-file-comment-shorter.zzip' returned error 21
+stdout opening 'incons-central-compsize-larger.zzip' returned error 21/6
+stdout opening 'incons-central-compsize-smaller.zzip' returned error 21/6
+stdout opening 'incons-central-crc.zzip' returned error 21/6
+stdout opening 'incons-central-date.zzip' returned error 21/6
+stdout opening 'incons-central-file-comment-longer.zzip' returned error 21/12
+stdout opening 'incons-central-file-comment-shorter.zzip' returned error 21/260
 stdout opening 'incons-central-magic-bad.zzip' returned error 19
 stdout opening 'incons-central-magic-bad2.zzip' returned error 19
-stdout opening 'incons-central-size-larger.zzip' returned error 21
+stdout opening 'incons-central-size-larger.zzip' returned error 21/6
 # tryopen does not test checksums, so this is fine.
 stdout opening 'incons-data.zzip' succeeded, 1 entries
-stdout opening 'incons-ef-central-size-wrong.zzip' returned error 21
-stdout opening 'incons-ef-local-id-size.zzip' returned error 21
+stdout opening 'incons-ef-central-size-wrong.zzip' returned error 21/16
+stdout opening 'incons-ef-local-id-size.zzip' returned error 21/16
 # different extra fields local vs. central is fine
 stdout opening 'incons-ef-local-id.zzip' succeeded, 1 entries
-stdout opening 'incons-ef-local-size.zzip' returned error 21
+stdout opening 'incons-ef-local-size.zzip' returned error 21/16
 stdout opening 'incons-eocd-magic-bad.zzip' returned error 19
-stdout opening 'incons-file-count-high.zzip' returned error 21
-stdout opening 'incons-file-count-low.zzip' returned error 21
-stdout opening 'incons-file-count-overflow.zzip' returned error 21
-stdout opening 'incons-local-compression-method.zzip' returned error 21
-stdout opening 'incons-local-compsize-larger.zzip' returned error 21
-stdout opening 'incons-local-compsize-smaller.zzip' returned error 21
-stdout opening 'incons-local-crc.zzip' returned error 21
+stdout opening 'incons-file-count-high.zzip' returned error 21/5
+stdout opening 'incons-file-count-low.zzip' returned error 21/5
+stdout opening 'incons-file-count-overflow.zzip' returned error 21/11
+stdout opening 'incons-local-compression-method.zzip' returned error 21/6
+stdout opening 'incons-local-compsize-larger.zzip' returned error 21/6
+stdout opening 'incons-local-compsize-smaller.zzip' returned error 21/6
+stdout opening 'incons-local-crc.zzip' returned error 21/6
 stdout opening 'incons-local-filename-long.zzip' returned error 17
-stdout opening 'incons-local-filename-missing.zzip' returned error 21
-stdout opening 'incons-local-filename-short.zzip' returned error 21
-stdout opening 'incons-local-filename.zzip' returned error 21
+stdout opening 'incons-local-filename-missing.zzip' returned error 21/6
+stdout opening 'incons-local-filename-short.zzip' returned error 21/16
+stdout opening 'incons-local-filename.zzip' returned error 21/6
 stdout opening 'incons-local-magic-bad.zzip' returned error 19
-stdout opening 'incons-local-size-larger.zzip' returned error 21
+stdout opening 'incons-local-size-larger.zzip' returned error 21/6
 stderr 31 errors
diff --git a/regress/open_many_fail.test b/regress/open_many_fail.test
index d0c154d..2b57e15 100644
--- a/regress/open_many_fail.test
+++ b/regress/open_many_fail.test
@@ -5,7 +5,7 @@
 file manyfiles-zip64-modulo.zzip manyfiles-zip64-modulo.zip manyfiles-zip64-modulo.zip
 file manyfiles-fewer.zzip manyfiles-fewer.zip manyfiles-fewer.zip
 file manyfiles-more.zzip manyfiles-more.zip manyfiles-more.zip
-stdout opening 'manyfiles-zip64-modulo.zzip' returned error 21
-stdout opening 'manyfiles-fewer.zzip' returned error 21
-stdout opening 'manyfiles-more.zzip' returned error 21
-stderr 3 errors
\ No newline at end of file
+stdout opening 'manyfiles-zip64-modulo.zzip' returned error 21/5
+stdout opening 'manyfiles-fewer.zzip' returned error 21/5
+stdout opening 'manyfiles-more.zzip' returned error 21/5
+stderr 3 errors
diff --git a/regress/tryopen.c b/regress/tryopen.c
index f4bb056..52ace93 100644
--- a/regress/tryopen.c
+++ b/regress/tryopen.c
@@ -93,8 +93,15 @@
         }
 
         printf("opening '%s' returned error %d", fname, ze);
-        if (zip_error_get_sys_type(ze) == ZIP_ET_SYS)
-            printf("/%d", errno);
+        switch (zip_error_get_sys_type(ze)) {
+            case ZIP_ET_SYS:
+            case ZIP_ET_LIBZIP:
+                printf("/%d", errno);
+                break;
+                
+            default:
+                break;
+        }
         printf("\n");
         error++;
     }