commit c8834821f452a3d424edd0ed2a1e9ceeda38d0ea
Author: Alex Danilo <adanilo@chromium.org>
Date:   Thu May 12 03:29:52 2022 +0000

    Extract: Parse Unicode Path Extra field in minizip
    
    Adds parsing of the Info-ZIP Extra field which overrides the
    file name in the File Header only if the CRC in the extra field
    is a CRC of the file name in the File Header.
    
    See https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT
    section 4.6.9 for reference.
    
    Also tidied up some whitespace indent.
    
    Bug: 953256, 953599
    Tests: Manually tested, auto test in follow on CL
    Change-Id: I1283dcb88a203c3bb56c1d9c504035a2e51aecbd
    Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3641742
    Reviewed-by: Noel Gordon <noel@chromium.org>
    Commit-Queue: Alex Danilo <adanilo@chromium.org>
    Cr-Commit-Position: refs/heads/main@{#1002476}

commit 5a56f75b0da23a10f2c6d9068029a00e53425ddf
Author: Hans Wennborg <hans@chromium.org>
Date:   Fri May 16 15:48:19 2025 +0200

    [minizip] Set filename length when using the Unicode Path Extra field

    This is a follow-up to crrev.com/1002476 which added support for parsing
    the Unicode Path Extra field, which overrides the regular filename. It
    also needs to update the filename length.

    Bug: 40623474
    Change-Id: Ifab65f470736b45b1b51a1cc130a5753a2b20583
    Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6553931

commit 9f6e08ef47d3bc9438fdc3b1ab77126a7b36cce9
Author: Hans Wennborg <hans@chromium.org>
Date:   Thu Jul 3 17:47:55 2025 +0200

    [minizip] Fix Unicode Path Extra Field filename length overflow

    If dataSize is too small, fileNameSize would overflow.

    Bug: 428744375
    Change-Id: I714fc1e30cb1634c31cb97ce87be225518368e57
    Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6701714

Author: Hans Wennborg <hans@chromium.org>
Date:   Fri Jul 11 13:04:30 2025 +0200

    [minizip] Fix potential OOB in unicode path extra field parsing

    The code needs to compare the CRC of the "regular" filename with the
    NameCRC32 value in the unicode path extra field. However, the caller may
    not have passed in a szFileName buffer large enough to hold the whole
    filename, or indeed any buffer at all.

    To fix this, always read the full filename into a temporary buffer, and
    compute the CRC on that.

    This also simplifies the logic for writing the filename to szFileName,
    at the expense of using a small bit of extra memory, which shouldn't be
    an issue for our use cases.

    Bug: 431119343
    Change-Id: Ib06e1009b6e25d2d14e36858385df46d72b7bc3e
    Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6725677

commit 8188181a34a48914bab22f0bc26b740fbdb38bd0
Author: Hans Wennborg <hans@chromium.org>
Date:   Mon Apr 27 13:24:27 2026 +0200

    [minizip] Store the filename from Unicode Path Extra Field separately
    
    Instead of overriding unz_file_info64's size_filename and writing it to
    szFileName, store the Unicode filename and its size in new fields.
    
    Overriding size_filename could cause unzGoToNextFile() to jump to the
    wrong offset, potentially skipping a file in the central directory,
    as demonstrated by a newly added test.
    
    Storing the Unicode filename and its size separately avoids that
    problem and lets the caller decide what to do with the filename. Besides
    fixing the problem above, that seems like a safer way of bolting on
    support for this functionality.
    
    Bug: 40623474, 500521311
    Change-Id: I06e6c8a8ff8baa729b10a67a998f8804803ae6cd
    Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7797172

diff --git a/third_party/zlib/contrib/minizip/unzip.c b/third_party/zlib/contrib/minizip/unzip.c
index 56f1468cd8d22..0264f7ac570f7 100644
--- a/third_party/zlib/contrib/minizip/unzip.c
+++ b/third_party/zlib/contrib/minizip/unzip.c
@@ -63,6 +63,7 @@
 */
 
 
+#include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -195,6 +196,26 @@ typedef struct
    Reads a long in LSB order from the given gz_stream. Sets
 */
 
+local int unz64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def,
+                             voidpf filestream,
+                             int *pi) {
+    unsigned char c;
+    int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1);
+    if (err==1)
+    {
+        *pi = (int)c;
+        return UNZ_OK;
+    }
+    else
+    {
+        *pi = 0;
+        if (ZERROR64(*pzlib_filefunc_def,filestream))
+            return UNZ_ERRNO;
+        else
+            return UNZ_EOF;
+    }
+}
+
 local int unz64local_getShort(const zlib_filefunc64_32_def* pzlib_filefunc_def,
                               voidpf filestream,
                               uLong *pX) {
@@ -836,6 +857,10 @@ local int unz64local_GetCurrentFileInfoInternal(unzFile file,
     uLong uMagic;
     long lSeek=0;
     uLong uL;
+    uLong uFileNameCrc;
+
+    file_info.size_utf8_filename = 0;
+    file_info.utf8_filename[0] = '\0';
 
     if (file==NULL)
         return UNZ_PARAMERROR;
@@ -907,21 +932,34 @@ local int unz64local_GetCurrentFileInfoInternal(unzFile file,
     file_info_internal.offset_curfile = uL;
 
     lSeek+=file_info.size_filename;
-    if ((err==UNZ_OK) && (szFileName!=NULL))
+    if (err==UNZ_OK)
     {
-        uLong uSizeRead ;
-        if (file_info.size_filename<fileNameBufferSize)
+        char szCurrentFileName[UINT16_MAX] = {0};
+
+        if (file_info.size_filename > 0)
         {
-            *(szFileName+file_info.size_filename)='\0';
-            uSizeRead = file_info.size_filename;
+            if (ZREAD64(s->z_filefunc, s->filestream, szCurrentFileName, file_info.size_filename) != file_info.size_filename)
+            {
+                err=UNZ_ERRNO;
+            }
         }
-        else
-            uSizeRead = fileNameBufferSize;
 
-        if ((file_info.size_filename>0) && (fileNameBufferSize>0))
-            if (ZREAD64(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)
-                err=UNZ_ERRNO;
-        lSeek -= uSizeRead;
+        uFileNameCrc = crc32(0, (unsigned char*)szCurrentFileName, file_info.size_filename);
+
+        if (szFileName != NULL)
+        {
+            if (fileNameBufferSize <= file_info.size_filename)
+            {
+                memcpy(szFileName, szCurrentFileName, fileNameBufferSize);
+            }
+            else
+            {
+                memcpy(szFileName, szCurrentFileName, file_info.size_filename);
+                szFileName[file_info.size_filename] = '\0';
+            }
+        }
+
+        lSeek -= file_info.size_filename;
     }
 
     /* Read extrafield */
@@ -1007,6 +1045,62 @@ local int unz64local_GetCurrentFileInfoInternal(unzFile file,
                 }
 
             }
+            else if (headerId == 0x7075) /* Info-ZIP Unicode Path Extra Field */
+            {
+                int version = 0;
+
+                if (dataSize < 1 + 4)
+                {
+                    /* dataSize includes version (1 byte), uCrc (4 bytes), and
+                     * the filename data. If it's too small, fileNameSize below
+                     * would overflow. */
+                    err = UNZ_ERRNO;
+                    break;
+                }
+                else if (unz64local_getByte(&s->z_filefunc, s->filestream, &version) != UNZ_OK)
+                {
+                    err = UNZ_ERRNO;
+                }
+                if (version != 1)
+                {
+                    if (ZSEEK64(s->z_filefunc, s->filestream,dataSize - 1, ZLIB_FILEFUNC_SEEK_CUR) != 0)
+                    {
+                        err = UNZ_ERRNO;
+                    }
+                }
+                else
+                {
+                    uLong uCrc, utf8FileNameSize;
+
+                    if (unz64local_getLong(&s->z_filefunc, s->filestream, &uCrc) != UNZ_OK)
+                    {
+                        err = UNZ_ERRNO;
+                    }
+                    utf8FileNameSize = dataSize - (1 + 4);  /* 1 for version, 4 for uCrc */
+
+                    /* Check CRC against file name in the header. */
+                    if (uCrc != uFileNameCrc)
+                    {
+                        if (ZSEEK64(s->z_filefunc, s->filestream, utf8FileNameSize, ZLIB_FILEFUNC_SEEK_CUR) != 0)
+                        {
+                            err = UNZ_ERRNO;
+                        }
+                    }
+                    else
+                    {
+                        file_info.size_utf8_filename = utf8FileNameSize;
+
+                        if (file_info.size_utf8_filename > 0)
+                        {
+                            if (ZREAD64(s->z_filefunc, s->filestream, file_info.utf8_filename, file_info.size_utf8_filename) != file_info.size_utf8_filename)
+                            {
+                                err = UNZ_ERRNO;
+                            }
+                        }
+                        file_info.utf8_filename[file_info.size_utf8_filename] = '\0';
+                    }
+                }
+            }
             else
             {
                 if (ZSEEK64(s->z_filefunc, s->filestream,dataSize,ZLIB_FILEFUNC_SEEK_CUR)!=0)
@@ -1106,6 +1200,9 @@ extern int ZEXPORT unzGetCurrentFileInfo(unzFile file,
         pfile_info->compressed_size = (uLong)file_info64.compressed_size;
         pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size;
 
+        pfile_info->size_utf8_filename = file_info64.size_utf8_filename;
+        memcpy(pfile_info->utf8_filename, file_info64.utf8_filename, file_info64.size_utf8_filename + 1);
+
     }
     return err;
 }
diff --git a/third_party/zlib/contrib/minizip/unzip.h b/third_party/zlib/contrib/minizip/unzip.h
index 9c98b608c7342..05efa64ea477e 100644
--- a/third_party/zlib/contrib/minizip/unzip.h
+++ b/third_party/zlib/contrib/minizip/unzip.h
@@ -42,6 +42,8 @@
 #ifndef _unz64_H
 #define _unz64_H
 
+#include <stdint.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -128,6 +130,10 @@ typedef struct unz_file_info64_s
     uLong external_fa;          /* external file attributes        4 bytes */
 
     tm_unz tmu_date;
+
+    /* Info-ZIP Unicode Path Extra Field */
+    char utf8_filename[UINT16_MAX + 1]; /* UTF-8 Filename, null terminated */
+    uLong size_utf8_filename;           /* Length, excluding null terminator */
 } unz_file_info64;
 
 typedef struct unz_file_info_s
@@ -149,6 +155,10 @@ typedef struct unz_file_info_s
     uLong external_fa;          /* external file attributes        4 bytes */
 
     tm_unz tmu_date;
+
+    /* Info-ZIP Unicode Path Extra Field */
+    char utf8_filename[UINT16_MAX + 1]; /* UTF-8 Filename, null terminated */
+    uLong size_utf8_filename;           /* Length, excluding null terminator */
 } unz_file_info;
 
 extern int ZEXPORT unzStringFileNameCompare(const char* fileName1,
