From 071499ac0d8e33e6f269437c3ce4fab52cc43f90 Mon Sep 17 00:00:00 2001 From: RedworkDE <10944644+RedworkDE@users.noreply.github.com> Date: Tue, 14 Feb 2023 17:29:35 +0100 Subject: [PATCH] Fix ZIPReader failing to open empty zip files --- .../minizip/patches/empty-zip-fix.patch | 193 ++++++++++++++++++ thirdparty/minizip/unzip.c | 92 +++++++-- 2 files changed, 263 insertions(+), 22 deletions(-) create mode 100644 thirdparty/minizip/patches/empty-zip-fix.patch diff --git a/thirdparty/minizip/patches/empty-zip-fix.patch b/thirdparty/minizip/patches/empty-zip-fix.patch new file mode 100644 index 00000000000..7885d4c3a39 --- /dev/null +++ b/thirdparty/minizip/patches/empty-zip-fix.patch @@ -0,0 +1,193 @@ +diff --git a/thirdparty/minizip/unzip.c b/thirdparty/minizip/unzip.c +index e83aff2773..af73f06137 100644 +--- a/thirdparty/minizip/unzip.c ++++ b/thirdparty/minizip/unzip.c +@@ -408,6 +408,12 @@ extern int ZEXPORT unzStringFileNameCompare (const char* fileName1, + #define BUFREADCOMMENT (0x400) + #endif + ++/* GODOT start */ ++#ifndef CENTRALDIRINVALID ++#define CENTRALDIRINVALID (0xffffffffffffffff) ++#endif ++/* GODOT end */ ++ + /* + Locate the Central directory of a zipfile (at the end, just before + the global comment) +@@ -419,10 +425,14 @@ local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_f + ZPOS64_T uSizeFile; + ZPOS64_T uBackRead; + ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ +- ZPOS64_T uPosFound=0; ++ /* GODOT start */ ++ ZPOS64_T uPosFound=CENTRALDIRINVALID; ++ /* GODOT end */ + + if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) +- return 0; ++ /* GODOT start */ ++ return CENTRALDIRINVALID; ++ /* GODOT end */ + + + uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); +@@ -432,7 +442,9 @@ local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_f + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf==NULL) +- return 0; ++ /* GODOT start */ ++ return CENTRALDIRINVALID; ++ /* GODOT end */ + + uBackRead = 4; + while (uBackRead<uMaxBack) +@@ -462,7 +474,9 @@ local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_f + break; + } + +- if (uPosFound!=0) ++ /* GODOT start */ ++ if (uPosFound!=CENTRALDIRINVALID) ++ /* GODOT end */ + break; + } + TRYFREE(buf); +@@ -485,12 +499,16 @@ local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib + ZPOS64_T uSizeFile; + ZPOS64_T uBackRead; + ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ +- ZPOS64_T uPosFound=0; ++ /* GODOT start */ ++ ZPOS64_T uPosFound=CENTRALDIRINVALID; ++ /* GODOT end */ + uLong uL; + ZPOS64_T relativeOffset; + + if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) +- return 0; ++ /* GODOT start */ ++ return CENTRALDIRINVALID; ++ /* GODOT end */ + + + uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); +@@ -500,7 +518,9 @@ local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf==NULL) +- return 0; ++ /* GODOT start */ ++ return CENTRALDIRINVALID; ++ /* GODOT end */ + + uBackRead = 4; + while (uBackRead<uMaxBack) +@@ -530,47 +550,71 @@ local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib + break; + } + +- if (uPosFound!=0) ++ /* GODOT start */ ++ if (uPosFound!=CENTRALDIRINVALID) ++ /* GODOT end */ + break; + } + TRYFREE(buf); +- if (uPosFound == 0) +- return 0; ++ /* GODOT start */ ++ if (uPosFound == CENTRALDIRINVALID) ++ return CENTRALDIRINVALID; ++ /* GODOT end */ + + /* Zip64 end of central directory locator */ + if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0) +- return 0; ++ /* GODOT start */ ++ return CENTRALDIRINVALID; ++ /* GODOT end */ + + /* the signature, already checked */ + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) +- return 0; ++ /* GODOT start */ ++ return CENTRALDIRINVALID; ++ /* GODOT end */ + + /* number of the disk with the start of the zip64 end of central directory */ + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) +- return 0; ++ /* GODOT start */ ++ return CENTRALDIRINVALID; ++ /* GODOT end */ + if (uL != 0) +- return 0; ++ /* GODOT start */ ++ return CENTRALDIRINVALID; ++ /* GODOT end */ + + /* relative offset of the zip64 end of central directory record */ + if (unz64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK) +- return 0; ++ /* GODOT start */ ++ return CENTRALDIRINVALID; ++ /* GODOT end */ + + /* total number of disks */ + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) +- return 0; ++ /* GODOT start */ ++ return CENTRALDIRINVALID; ++ /* GODOT end */ + if (uL != 1) +- return 0; ++ /* GODOT start */ ++ return CENTRALDIRINVALID; ++ /* GODOT end */ + + /* Goto end of central directory record */ + if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0) +- return 0; ++ /* GODOT start */ ++ return CENTRALDIRINVALID; ++ /* GODOT end */ + + /* the signature */ + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) +- return 0; ++ /* GODOT start */ ++ return CENTRALDIRINVALID; ++ /* GODOT end */ + + if (uL != 0x06064b50) +- return 0; ++ /* GODOT start */ ++ return CENTRALDIRINVALID; ++ /* GODOT end */ + + return relativeOffset; + } +@@ -625,7 +669,9 @@ local unzFile unzOpenInternal (const void *path, + return NULL; + + central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream); +- if (central_pos) ++ /* GODOT start */ ++ if (central_pos != CENTRALDIRINVALID) ++ /* GODOT end */ + { + uLong uS; + ZPOS64_T uL64; +@@ -687,7 +733,9 @@ local unzFile unzOpenInternal (const void *path, + else + { + central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream); +- if (central_pos==0) ++ /* GODOT start */ ++ if (central_pos==CENTRALDIRINVALID) ++ /* GODOT end */ + err=UNZ_ERRNO; + + us.isZip64 = 0; diff --git a/thirdparty/minizip/unzip.c b/thirdparty/minizip/unzip.c index e83aff2773d..f72bf3974f3 100644 --- a/thirdparty/minizip/unzip.c +++ b/thirdparty/minizip/unzip.c @@ -408,6 +408,12 @@ extern int ZEXPORT unzStringFileNameCompare (const char* fileName1, #define BUFREADCOMMENT (0x400) #endif +/* GODOT start */ +#ifndef CENTRALDIRINVALID +#define CENTRALDIRINVALID (0xffffffffffffffff) +#endif +/* GODOT end */ + /* Locate the Central directory of a zipfile (at the end, just before the global comment) @@ -419,10 +425,14 @@ local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_f ZPOS64_T uSizeFile; ZPOS64_T uBackRead; ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ - ZPOS64_T uPosFound=0; + /* GODOT start */ + ZPOS64_T uPosFound=CENTRALDIRINVALID; + /* GODOT end */ if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) - return 0; + /* GODOT start */ + return CENTRALDIRINVALID; + /* GODOT end */ uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); @@ -432,7 +442,9 @@ local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_f buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); if (buf==NULL) - return 0; + /* GODOT start */ + return CENTRALDIRINVALID; + /* GODOT end */ uBackRead = 4; while (uBackRead<uMaxBack) @@ -462,7 +474,9 @@ local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_f break; } - if (uPosFound!=0) + /* GODOT start */ + if (uPosFound!=CENTRALDIRINVALID) + /* GODOT end */ break; } TRYFREE(buf); @@ -485,12 +499,16 @@ local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib ZPOS64_T uSizeFile; ZPOS64_T uBackRead; ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ - ZPOS64_T uPosFound=0; + /* GODOT start */ + ZPOS64_T uPosFound=CENTRALDIRINVALID; + /* GODOT end */ uLong uL; ZPOS64_T relativeOffset; if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) - return 0; + /* GODOT start */ + return CENTRALDIRINVALID; + /* GODOT end */ uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); @@ -500,7 +518,9 @@ local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); if (buf==NULL) - return 0; + /* GODOT start */ + return CENTRALDIRINVALID; + /* GODOT end */ uBackRead = 4; while (uBackRead<uMaxBack) @@ -530,47 +550,71 @@ local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib break; } - if (uPosFound!=0) + /* GODOT start */ + if (uPosFound!=CENTRALDIRINVALID) + /* GODOT end */ break; } TRYFREE(buf); - if (uPosFound == 0) - return 0; + /* GODOT start */ + if (uPosFound == CENTRALDIRINVALID) + return CENTRALDIRINVALID; + /* GODOT end */ /* Zip64 end of central directory locator */ if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0) - return 0; + /* GODOT start */ + return CENTRALDIRINVALID; + /* GODOT end */ /* the signature, already checked */ if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) - return 0; + /* GODOT start */ + return CENTRALDIRINVALID; + /* GODOT end */ /* number of the disk with the start of the zip64 end of central directory */ if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) - return 0; + /* GODOT start */ + return CENTRALDIRINVALID; + /* GODOT end */ if (uL != 0) - return 0; + /* GODOT start */ + return CENTRALDIRINVALID; + /* GODOT end */ /* relative offset of the zip64 end of central directory record */ if (unz64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK) - return 0; + /* GODOT start */ + return CENTRALDIRINVALID; + /* GODOT end */ /* total number of disks */ if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) - return 0; + /* GODOT start */ + return CENTRALDIRINVALID; + /* GODOT end */ if (uL != 1) - return 0; + /* GODOT start */ + return CENTRALDIRINVALID; + /* GODOT end */ /* Goto end of central directory record */ if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0) - return 0; + /* GODOT start */ + return CENTRALDIRINVALID; + /* GODOT end */ /* the signature */ if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) - return 0; + /* GODOT start */ + return CENTRALDIRINVALID; + /* GODOT end */ if (uL != 0x06064b50) - return 0; + /* GODOT start */ + return CENTRALDIRINVALID; + /* GODOT end */ return relativeOffset; } @@ -625,7 +669,9 @@ local unzFile unzOpenInternal (const void *path, return NULL; central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream); - if (central_pos) + /* GODOT start */ + if (central_pos != CENTRALDIRINVALID) + /* GODOT end */ { uLong uS; ZPOS64_T uL64; @@ -687,7 +733,9 @@ local unzFile unzOpenInternal (const void *path, else { central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream); - if (central_pos==0) + /* GODOT start */ + if (central_pos==CENTRALDIRINVALID) + /* GODOT end */ err=UNZ_ERRNO; us.isZip64 = 0;