Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

minizip: Fix ZIPReader failing to open empty zip files #73310

Merged
merged 1 commit into from
Jul 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
193 changes: 193 additions & 0 deletions thirdparty/minizip/patches/empty-zip-fix.patch
Original file line number Diff line number Diff line change
@@ -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;
92 changes: 70 additions & 22 deletions thirdparty/minizip/unzip.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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);
Expand All @@ -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)
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -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)
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down