Commit bd5cbdd for zlib

commit bd5cbdd142f34181c1dbf8e3f8ca4b1821387a52
Author: Mark Adler <git@madler.net>
Date:   Tue Nov 3 09:12:01 2026 -0800

    Avoid corrupt zip headers from Zip64 extra field overflows.

    The extra field in a local or central directory header is
    limited to 65535 bytes. Minizip's zip code would check that the
    application provided no more than that. However zip adds a Zip64
    subfield to the local header extra field when the application
    requests zip64, and to the central directory extra field when an
    offset or size is 2^32-1 or more. If that would bump the extra
    data over 65535 bytes, then a corrupt local or central directory
    header would be written.

    This is now detected, and an error is returned when the entry is
    opened (local overage) or when it is closed (central directory
    overage). In the latter case, the entry is left out of the central
    directory, so that the zip file can still be completed with its
    other entries if desired.

    Thanks to itsgaldoron <dorongal1@gmail.com> for the report.

diff --git a/contrib/minizip/zip.c b/contrib/minizip/zip.c
index 58a84bf..1d6869b 100644
--- a/contrib/minizip/zip.c
+++ b/contrib/minizip/zip.c
@@ -1341,10 +1341,12 @@ extern int ZEXPORT zipOpenNewFileInZip4_64(zipFile file, const char* filename, c
         return ZIP_PARAMERROR;
     if ((comment!=NULL) && (strlen(comment)>0xffff))
         return ZIP_PARAMERROR;
-    /* The extra field length must fit in 16 bits. If the member also requires
-       a Zip64 extra block, that will also need to fit within that 16-bit
-       length, but that will be checked for later. */
-    if ((size_extrafield_local>0xffff) || (size_extrafield_global>0xffff))
+    /* The extra field lengths must fit in 16 bits, including a 20-byte
+       Zip64 sub-field in the local header if zip64 is true. There might
+       be a Zip64 sub-field needed in the central directory header as
+       well, but that won't be known until later. */
+    if ((size_extrafield_local>(0xffff-(zip64?20:0))) ||
+        (size_extrafield_global>0xffff))
         return ZIP_PARAMERROR;

     zi = (zip64_internal*)file;
@@ -1903,9 +1905,14 @@ extern int ZEXPORT zipCloseFileInZipRaw64(zipFile file, ZPOS64_T uncompressed_si
       char* p = NULL;
       uLong size_comment;

-      if((uLong)(datasize + 4) > zi->ci.size_centralExtraFree)
+      if (zi->ci.size_centralExtra + datasize + 4 > 0xffff)
       {
-        /* we cannot write more data to the buffer that we have room for. */
+        /* the extra field is now too big with the Zip64 sub-field -- leave
+           this entry out of the central directory, so that the zip file can be
+           completed with the remaining entries, if desired */
+        free(zi->ci.central_header);
+        zi->ci.central_header = NULL;
+        zi->in_opened_file_inzip = 0;
         return ZIP_BADZIPFILE;
       }

diff --git a/contrib/minizip/zip.h b/contrib/minizip/zip.h
index 9962440..d4f3111 100644
--- a/contrib/minizip/zip.h
+++ b/contrib/minizip/zip.h
@@ -181,9 +181,14 @@ extern int ZEXPORT zipOpenNewFileInZip64(zipFile file,
     contains the extrafield data for the local header
   if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global
     contains the extrafield data for the global header
-  if comment != NULL, comment contain the comment string
-  method contain the compression method (0 for store, Z_DEFLATED for deflate)
-  level contain the level of compression (can be Z_DEFAULT_COMPRESSION)
+  size_extrafield_local and size_extrafield_global are limited to 65535 by
+    the format, or less depending on the presence of Zip64 subfields --
+    size_extrafield_local needs to leave room for a 20-byte Zip64 subfield if
+    zip64 is true, and size_extrafield_global needs to leave room for a 12 to
+    28 byte Zip64 subfield in case the offset or length exceeds 2^32-1
+  if comment != NULL, comment contains the comment string
+  method contains the compression method (0 for store, Z_DEFLATED for deflate)
+  level contains the level of compression (can be Z_DEFAULT_COMPRESSION)
   zip64 is set to 1 if a zip64 extended information block should be added to the local file header.
                     this MUST be '1' if the uncompressed size is >= 0xffffffff.