Merge branch 'holy-zip' into 'next'
Disallow pk3s with extra bytes See merge request STJr/SRB2!1275
This commit is contained in:
commit
f180a1fc3c
|
@ -998,7 +998,7 @@ static void IdentifyVersion(void)
|
||||||
#define MUSICTEST(str) \
|
#define MUSICTEST(str) \
|
||||||
{\
|
{\
|
||||||
const char *musicpath = va(pandf,srb2waddir,str);\
|
const char *musicpath = va(pandf,srb2waddir,str);\
|
||||||
int ms = W_VerifyNMUSlumps(musicpath); \
|
int ms = W_VerifyNMUSlumps(musicpath, false); \
|
||||||
if (ms == 1) \
|
if (ms == 1) \
|
||||||
D_AddFile(startupwadfiles, musicpath); \
|
D_AddFile(startupwadfiles, musicpath); \
|
||||||
else if (ms == 0) \
|
else if (ms == 0) \
|
||||||
|
@ -1187,14 +1187,10 @@ void D_SRB2Main(void)
|
||||||
const char *s = M_GetNextParm();
|
const char *s = M_GetNextParm();
|
||||||
|
|
||||||
if (s) // Check for NULL?
|
if (s) // Check for NULL?
|
||||||
{
|
|
||||||
if (!W_VerifyNMUSlumps(s))
|
|
||||||
G_SetGameModified(true);
|
|
||||||
D_AddFile(startuppwads, s);
|
D_AddFile(startuppwads, s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// get map from parms
|
// get map from parms
|
||||||
|
|
||||||
|
|
|
@ -3294,7 +3294,13 @@ static void Command_Addfile(void)
|
||||||
if (!isprint(fn[i]) || fn[i] == ';')
|
if (!isprint(fn[i]) || fn[i] == ';')
|
||||||
return;
|
return;
|
||||||
|
|
||||||
musiconly = W_VerifyNMUSlumps(fn);
|
musiconly = W_VerifyNMUSlumps(fn, false);
|
||||||
|
|
||||||
|
if (musiconly == -1)
|
||||||
|
{
|
||||||
|
addedfiles[numfilesadded++] = fn;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (!musiconly)
|
if (!musiconly)
|
||||||
{
|
{
|
||||||
|
|
90
src/w_wad.c
90
src/w_wad.c
|
@ -66,6 +66,7 @@
|
||||||
#include "p_setup.h" // P_ScanThings
|
#include "p_setup.h" // P_ScanThings
|
||||||
#endif
|
#endif
|
||||||
#include "m_misc.h" // M_MapNumber
|
#include "m_misc.h" // M_MapNumber
|
||||||
|
#include "g_game.h" // G_SetGameModified
|
||||||
|
|
||||||
#ifdef HWRENDER
|
#ifdef HWRENDER
|
||||||
#include "hardware/hw_main.h"
|
#include "hardware/hw_main.h"
|
||||||
|
@ -683,9 +684,9 @@ static UINT16 W_InitFileError (const char *filename, boolean exitworthy)
|
||||||
if (exitworthy)
|
if (exitworthy)
|
||||||
{
|
{
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
CONS_Error("A WAD file was not found or not valid.\nCheck the log to see which ones.\n");
|
CONS_Error(va("%s was not found or not valid.\nCheck the log for more details.\n", filename));
|
||||||
#else
|
#else
|
||||||
I_Error("A WAD file was not found or not valid.\nCheck the log to see which ones.\n");
|
I_Error("%s was not found or not valid.\nCheck the log for more details.\n", filename);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -716,7 +717,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 +747,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, startup);
|
||||||
|
|
||||||
|
if (important == -1)
|
||||||
|
{
|
||||||
|
fclose(handle);
|
||||||
|
return INT16_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
// 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;
|
||||||
|
|
||||||
|
@ -811,6 +820,9 @@ UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup)
|
||||||
return W_InitFileError(filename, startup);
|
return W_InitFileError(filename, startup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (important && !mainfile)
|
||||||
|
G_SetGameModified(true);
|
||||||
|
|
||||||
//
|
//
|
||||||
// link wad file to search files
|
// link wad file to search files
|
||||||
//
|
//
|
||||||
|
@ -1919,8 +1931,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 +1956,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 +1965,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 +1981,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 +2002,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,10 +2015,47 @@ 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
|
||||||
// deal with compressed lumps.
|
// deal with compressed lumps.
|
||||||
static int W_VerifyFile(const char *filename, lumpchecklist_t *checklist,
|
static int W_VerifyFile(const char *filename, lumpchecklist_t *checklist,
|
||||||
|
@ -2029,12 +2092,13 @@ static int W_VerifyFile(const char *filename, lumpchecklist_t *checklist,
|
||||||
* be sent.
|
* be sent.
|
||||||
*
|
*
|
||||||
* \param filename Filename of the wad to check.
|
* \param filename Filename of the wad to check.
|
||||||
|
* \param exit_on_error Whether to exit upon file error.
|
||||||
* \return 1 if file contains only music/sound lumps, 0 if it contains other
|
* \return 1 if file contains only music/sound lumps, 0 if it contains other
|
||||||
* stuff (maps, sprites, dehacked lumps, and so on). -1 if there no
|
* stuff (maps, sprites, dehacked lumps, and so on). -1 if there no
|
||||||
* file exists with that filename
|
* file exists with that filename
|
||||||
* \author Alam Arias
|
* \author Alam Arias
|
||||||
*/
|
*/
|
||||||
int W_VerifyNMUSlumps(const char *filename)
|
int W_VerifyNMUSlumps(const char *filename, boolean exit_on_error)
|
||||||
{
|
{
|
||||||
// MIDI, MOD/S3M/IT/XM/OGG/MP3/WAV, WAVE SFX
|
// MIDI, MOD/S3M/IT/XM/OGG/MP3/WAV, WAVE SFX
|
||||||
// ENDOOM text and palette lumps
|
// ENDOOM text and palette lumps
|
||||||
|
@ -2108,7 +2172,13 @@ int W_VerifyNMUSlumps(const char *filename)
|
||||||
|
|
||||||
{NULL, 0},
|
{NULL, 0},
|
||||||
};
|
};
|
||||||
return W_VerifyFile(filename, NMUSlist, false);
|
|
||||||
|
int status = W_VerifyFile(filename, NMUSlist, false);
|
||||||
|
|
||||||
|
if (status == -1)
|
||||||
|
W_InitFileError(filename, exit_on_error);
|
||||||
|
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \brief Generates a virtual resource used for level data loading.
|
/** \brief Generates a virtual resource used for level data loading.
|
||||||
|
|
|
@ -206,6 +206,6 @@ void W_UnlockCachedPatch(void *patch);
|
||||||
|
|
||||||
void W_VerifyFileMD5(UINT16 wadfilenum, const char *matchmd5);
|
void W_VerifyFileMD5(UINT16 wadfilenum, const char *matchmd5);
|
||||||
|
|
||||||
int W_VerifyNMUSlumps(const char *filename);
|
int W_VerifyNMUSlumps(const char *filename, boolean exit_on_error);
|
||||||
|
|
||||||
#endif // __W_WAD__
|
#endif // __W_WAD__
|
||||||
|
|
Loading…
Reference in a new issue