Don't add pk3 if there are holes

ZIP tools often read the final central directory, but SRB2 may not if there are
multiple central directories. It's just easier to not allow "holes", or
unaccounted for bytes in the file.
This commit is contained in:
James R 2020-11-28 20:00:01 -08:00
parent d6ed2f4ac8
commit 0587b89b93

View file

@ -716,7 +716,7 @@ UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup)
#endif #endif
size_t packetsize; size_t packetsize;
UINT8 md5sum[16]; UINT8 md5sum[16];
boolean important; int important;
if (!(refreshdirmenu & REFRESHDIR_ADDFILE)) if (!(refreshdirmenu & REFRESHDIR_ADDFILE))
refreshdirmenu = REFRESHDIR_NORMAL|REFRESHDIR_ADDFILE; // clean out cons_alerts that happened earlier refreshdirmenu = REFRESHDIR_NORMAL|REFRESHDIR_ADDFILE; // clean out cons_alerts that happened earlier
@ -746,10 +746,18 @@ UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup)
if ((handle = W_OpenWadFile(&filename, true)) == NULL) if ((handle = W_OpenWadFile(&filename, true)) == NULL)
return W_InitFileError(filename, startup); return W_InitFileError(filename, startup);
important = W_VerifyNMUSlumps(filename);
if (important == -1)
{
fclose(handle);
return W_InitFileError(filename, startup);
}
// Check if wad files will overflow fileneededbuffer. Only the filename part // Check if wad files will overflow fileneededbuffer. Only the filename part
// is send in the packet; cf. // is send in the packet; cf.
// see PutFileNeeded in d_netfil.c // see PutFileNeeded in d_netfil.c
if ((important = !W_VerifyNMUSlumps(filename))) if ((important = !important))
{ {
packetsize = packetsizetally + nameonlylength(filename) + 22; packetsize = packetsizetally + nameonlylength(filename) + 22;
@ -1919,8 +1927,16 @@ static lumpchecklist_t folderblacklist[] =
static int static int
W_VerifyPK3 (FILE *fp, lumpchecklist_t *checklist, boolean status) W_VerifyPK3 (FILE *fp, lumpchecklist_t *checklist, boolean status)
{ {
int verified = true;
zend_t zend; zend_t zend;
zentry_t zentry; zentry_t zentry;
zlentry_t zlentry;
long file_size;/* size of zip file */
long data_size;/* size of data inside zip file */
long old_position;
UINT16 numlumps; UINT16 numlumps;
size_t i; size_t i;
@ -1936,6 +1952,8 @@ W_VerifyPK3 (FILE *fp, lumpchecklist_t *checklist, boolean status)
// Central directory bullshit // Central directory bullshit
fseek(fp, 0, SEEK_END); fseek(fp, 0, SEEK_END);
file_size = ftell(fp);
if (!ResFindSignature(fp, pat_end, max(0, ftell(fp) - (22 + 65536)))) if (!ResFindSignature(fp, pat_end, max(0, ftell(fp) - (22 + 65536))))
return true; return true;
@ -1943,6 +1961,8 @@ W_VerifyPK3 (FILE *fp, lumpchecklist_t *checklist, boolean status)
if (fread(&zend, 1, sizeof zend, fp) < sizeof zend) if (fread(&zend, 1, sizeof zend, fp) < sizeof zend)
return true; return true;
data_size = sizeof zend;
numlumps = zend.entries; numlumps = zend.entries;
fseek(fp, zend.cdiroffset, SEEK_SET); fseek(fp, zend.cdiroffset, SEEK_SET);
@ -1957,6 +1977,8 @@ W_VerifyPK3 (FILE *fp, lumpchecklist_t *checklist, boolean status)
if (memcmp(zentry.signature, pat_central, 4)) if (memcmp(zentry.signature, pat_central, 4))
return true; return true;
if (verified == true)
{
fullname = malloc(zentry.namelen + 1); fullname = malloc(zentry.namelen + 1);
if (fgets(fullname, zentry.namelen + 1, fp) != fullname) if (fgets(fullname, zentry.namelen + 1, fp) != fullname)
return true; return true;
@ -1976,11 +1998,11 @@ W_VerifyPK3 (FILE *fp, lumpchecklist_t *checklist, boolean status)
strncpy(lumpname, trimname, min(8, dotpos - trimname)); strncpy(lumpname, trimname, min(8, dotpos - trimname));
if (! W_VerifyName(lumpname, checklist, status)) if (! W_VerifyName(lumpname, checklist, status))
return false; verified = false;
// Check for directories next, if it's blacklisted it will return false // Check for directories next, if it's blacklisted it will return false
if (W_VerifyName(fullname, folderblacklist, status)) else if (W_VerifyName(fullname, folderblacklist, status))
return false; verified = false;
} }
free(fullname); free(fullname);
@ -1989,8 +2011,45 @@ W_VerifyPK3 (FILE *fp, lumpchecklist_t *checklist, boolean status)
if (fseek(fp, zentry.xtralen + zentry.commlen, SEEK_CUR) != 0) if (fseek(fp, zentry.xtralen + zentry.commlen, SEEK_CUR) != 0)
return true; return true;
} }
else
{
if (fseek(fp, zentry.namelen + zentry.xtralen + zentry.commlen, SEEK_CUR) != 0)
return true; return true;
}
data_size +=
sizeof zentry + zentry.namelen + zentry.xtralen + zentry.commlen;
old_position = ftell(fp);
if (fseek(fp, zentry.offset, SEEK_SET) != 0)
return true;
if (fread(&zlentry, 1, sizeof(zlentry_t), fp) < sizeof (zlentry_t))
return true;
data_size +=
sizeof zlentry + zlentry.namelen + zlentry.xtralen + zlentry.compsize;
fseek(fp, old_position, SEEK_SET);
}
if (data_size < file_size)
{
const char * error = "ZIP file has holes (%ld extra bytes)\n";
CONS_Alert(CONS_ERROR, error, (file_size - data_size));
return -1;
}
else if (data_size > file_size)
{
const char * error = "Reported size of ZIP file contents exceeds file size (%ld extra bytes)\n";
CONS_Alert(CONS_ERROR, error, (data_size - file_size));
return -1;
}
else
{
return verified;
}
} }
// Note: This never opens lumps themselves and therefore doesn't have to // Note: This never opens lumps themselves and therefore doesn't have to