Fix ZIPReader failing to open empty zip files

This commit is contained in:
RedworkDE 2023-02-14 17:29:35 +01:00
parent 830eff64a7
commit 071499ac0d
2 changed files with 263 additions and 22 deletions

View File

@ -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;

View File

@ -408,6 +408,12 @@ extern int ZEXPORT unzStringFileNameCompare (const char* fileName1,
#define BUFREADCOMMENT (0x400) #define BUFREADCOMMENT (0x400)
#endif #endif
/* GODOT start */
#ifndef CENTRALDIRINVALID
#define CENTRALDIRINVALID (0xffffffffffffffff)
#endif
/* GODOT end */
/* /*
Locate the Central directory of a zipfile (at the end, just before Locate the Central directory of a zipfile (at the end, just before
the global comment) the global comment)
@ -419,10 +425,14 @@ local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_f
ZPOS64_T uSizeFile; ZPOS64_T uSizeFile;
ZPOS64_T uBackRead; ZPOS64_T uBackRead;
ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ 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) 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); 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); buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
if (buf==NULL) if (buf==NULL)
return 0; /* GODOT start */
return CENTRALDIRINVALID;
/* GODOT end */
uBackRead = 4; uBackRead = 4;
while (uBackRead<uMaxBack) while (uBackRead<uMaxBack)
@ -462,7 +474,9 @@ local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_f
break; break;
} }
if (uPosFound!=0) /* GODOT start */
if (uPosFound!=CENTRALDIRINVALID)
/* GODOT end */
break; break;
} }
TRYFREE(buf); TRYFREE(buf);
@ -485,12 +499,16 @@ local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib
ZPOS64_T uSizeFile; ZPOS64_T uSizeFile;
ZPOS64_T uBackRead; ZPOS64_T uBackRead;
ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
ZPOS64_T uPosFound=0; /* GODOT start */
ZPOS64_T uPosFound=CENTRALDIRINVALID;
/* GODOT end */
uLong uL; uLong uL;
ZPOS64_T relativeOffset; ZPOS64_T relativeOffset;
if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) 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); 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); buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
if (buf==NULL) if (buf==NULL)
return 0; /* GODOT start */
return CENTRALDIRINVALID;
/* GODOT end */
uBackRead = 4; uBackRead = 4;
while (uBackRead<uMaxBack) while (uBackRead<uMaxBack)
@ -530,47 +550,71 @@ local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib
break; break;
} }
if (uPosFound!=0) /* GODOT start */
if (uPosFound!=CENTRALDIRINVALID)
/* GODOT end */
break; break;
} }
TRYFREE(buf); TRYFREE(buf);
if (uPosFound == 0) /* GODOT start */
return 0; if (uPosFound == CENTRALDIRINVALID)
return CENTRALDIRINVALID;
/* GODOT end */
/* Zip64 end of central directory locator */ /* Zip64 end of central directory locator */
if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0) if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0)
return 0; /* GODOT start */
return CENTRALDIRINVALID;
/* GODOT end */
/* the signature, already checked */ /* the signature, already checked */
if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) 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 */ /* number of the disk with the start of the zip64 end of central directory */
if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
return 0; /* GODOT start */
return CENTRALDIRINVALID;
/* GODOT end */
if (uL != 0) if (uL != 0)
return 0; /* GODOT start */
return CENTRALDIRINVALID;
/* GODOT end */
/* relative offset of the zip64 end of central directory record */ /* relative offset of the zip64 end of central directory record */
if (unz64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK) if (unz64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK)
return 0; /* GODOT start */
return CENTRALDIRINVALID;
/* GODOT end */
/* total number of disks */ /* total number of disks */
if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
return 0; /* GODOT start */
return CENTRALDIRINVALID;
/* GODOT end */
if (uL != 1) if (uL != 1)
return 0; /* GODOT start */
return CENTRALDIRINVALID;
/* GODOT end */
/* Goto end of central directory record */ /* Goto end of central directory record */
if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0) if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0)
return 0; /* GODOT start */
return CENTRALDIRINVALID;
/* GODOT end */
/* the signature */ /* the signature */
if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
return 0; /* GODOT start */
return CENTRALDIRINVALID;
/* GODOT end */
if (uL != 0x06064b50) if (uL != 0x06064b50)
return 0; /* GODOT start */
return CENTRALDIRINVALID;
/* GODOT end */
return relativeOffset; return relativeOffset;
} }
@ -625,7 +669,9 @@ local unzFile unzOpenInternal (const void *path,
return NULL; return NULL;
central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream); central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream);
if (central_pos) /* GODOT start */
if (central_pos != CENTRALDIRINVALID)
/* GODOT end */
{ {
uLong uS; uLong uS;
ZPOS64_T uL64; ZPOS64_T uL64;
@ -687,7 +733,9 @@ local unzFile unzOpenInternal (const void *path,
else else
{ {
central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream); central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream);
if (central_pos==0) /* GODOT start */
if (central_pos==CENTRALDIRINVALID)
/* GODOT end */
err=UNZ_ERRNO; err=UNZ_ERRNO;
us.isZip64 = 0; us.isZip64 = 0;