mirror of
https://github.com/w23/xash3d-fwgs
synced 2024-12-15 05:29:51 +01:00
engine: simplify blue shift swapped lump check, change TestBmodelLumps to avoid reading past mod buffer
This commit is contained in:
parent
07e622f224
commit
df1c9a5029
@ -80,8 +80,9 @@ int Cmd_ListMaps( search_t *t, char *lastmapname, size_t len )
|
||||
|
||||
if( f )
|
||||
{
|
||||
dheader_t *header;
|
||||
dheader_t *header;
|
||||
dextrahdr_t *hdrext;
|
||||
dlump_t entities;
|
||||
|
||||
memset( buf, 0, sizeof( buf ));
|
||||
FS_Read( f, buf, sizeof( buf ));
|
||||
@ -89,10 +90,10 @@ int Cmd_ListMaps( search_t *t, char *lastmapname, size_t len )
|
||||
ver = header->version;
|
||||
|
||||
// check all the lumps and some other errors
|
||||
if( Mod_TestBmodelLumps( t->filenames[i], buf, true ))
|
||||
if( Mod_TestBmodelLumps( f, t->filenames[i], buf, true, &entities ))
|
||||
{
|
||||
lumpofs = header->lumps[LUMP_ENTITIES].fileofs;
|
||||
lumplen = header->lumps[LUMP_ENTITIES].filelen;
|
||||
lumpofs = entities.fileofs;
|
||||
lumplen = entities.filelen;
|
||||
ver = header->version;
|
||||
}
|
||||
|
||||
@ -904,21 +905,22 @@ qboolean Cmd_CheckMapsList_R( qboolean fRefresh, qboolean onlyingamedir )
|
||||
{
|
||||
int num_spawnpoints = 0;
|
||||
dheader_t *header;
|
||||
dlump_t entities;
|
||||
|
||||
memset( buf, 0, MAX_SYSPATH );
|
||||
FS_Read( f, buf, MAX_SYSPATH );
|
||||
header = (dheader_t *)buf;
|
||||
|
||||
// check all the lumps and some other errors
|
||||
if( !Mod_TestBmodelLumps( t->filenames[i], buf, true ))
|
||||
if( !Mod_TestBmodelLumps( f, t->filenames[i], buf, true, &entities ))
|
||||
{
|
||||
FS_Close( f );
|
||||
continue;
|
||||
}
|
||||
|
||||
// after call Mod_TestBmodelLumps we gurantee what map is valid
|
||||
lumpofs = header->lumps[LUMP_ENTITIES].fileofs;
|
||||
lumplen = header->lumps[LUMP_ENTITIES].filelen;
|
||||
lumpofs = entities.fileofs;
|
||||
lumplen = entities.filelen;
|
||||
|
||||
Q_strncpy( entfilename, t->filenames[i], sizeof( entfilename ));
|
||||
COM_StripExtension( entfilename );
|
||||
|
@ -2738,33 +2738,14 @@ static void Mod_LoadLighting( dbspmodel_t *bmod )
|
||||
|
||||
/*
|
||||
=================
|
||||
Mod_LumpLooksLikePlanes
|
||||
Mod_LumpLooksLikeEntities
|
||||
|
||||
=================
|
||||
*/
|
||||
static qboolean Mod_LumpLooksLikePlanes( const byte *in, dlump_t *lump, qboolean fast )
|
||||
static int Mod_LumpLooksLikeEntities( const char *lump, const size_t lumplen )
|
||||
{
|
||||
int numplanes, i;
|
||||
const dplane_t *planes;
|
||||
|
||||
if( lump->filelen < sizeof( dplane_t ) &&
|
||||
lump->filelen % sizeof( dplane_t ) != 0 )
|
||||
return false;
|
||||
|
||||
if( fast )
|
||||
return true;
|
||||
|
||||
numplanes = lump->filelen / sizeof( dplane_t );
|
||||
planes = (const dplane_t*)(in + lump->fileofs);
|
||||
|
||||
for( i = 0; i < numplanes; i++ )
|
||||
{
|
||||
// planes can only be from 0 to 5: PLANE_X, Y, Z and PLANE_ANYX, Y and Z
|
||||
if( planes[i].type < 0 || planes[i].type > 5 )
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
// look for "classname" string
|
||||
return Q_memmem( lump, lumplen, "\"classname\"", sizeof( "\"classname\"" ) - 1 ) != NULL ? 1 : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2800,44 +2781,30 @@ qboolean Mod_LoadBmodelLumps( const byte *mod_base, qboolean isworld )
|
||||
#endif
|
||||
switch( header->version )
|
||||
{
|
||||
case Q1BSP_VERSION:
|
||||
case HLBSP_VERSION:
|
||||
// only relevant for half-life maps
|
||||
if( !Mod_LumpLooksLikeEntities( mod_base + header->lumps[LUMP_ENTITIES].fileofs, header->lumps[LUMP_ENTITIES].filelen ) &&
|
||||
Mod_LumpLooksLikeEntities( mod_base + header->lumps[LUMP_PLANES].fileofs, header->lumps[LUMP_PLANES].filelen ))
|
||||
{
|
||||
// blue-shift swapped lumps
|
||||
srclumps[0].lumpnumber = LUMP_PLANES;
|
||||
srclumps[1].lumpnumber = LUMP_ENTITIES;
|
||||
break;
|
||||
}
|
||||
// intended fallthrough
|
||||
case Q1BSP_VERSION:
|
||||
case QBSP2_VERSION:
|
||||
// everything else
|
||||
srclumps[0].lumpnumber = LUMP_ENTITIES;
|
||||
srclumps[1].lumpnumber = LUMP_PLANES;
|
||||
break;
|
||||
default:
|
||||
Con_Printf( S_ERROR "%s has wrong version number (%i should be %i)\n", loadmodel->name, header->version, HLBSP_VERSION );
|
||||
loadstat.numerrors++;
|
||||
return false;
|
||||
}
|
||||
|
||||
bmod->version = header->version; // share up global
|
||||
if( isworld ) world.flags = 0; // clear world settings
|
||||
bmod->isworld = isworld;
|
||||
|
||||
if( header->version == HLBSP_VERSION )
|
||||
{
|
||||
// only relevant for half-life maps
|
||||
if( !Mod_LumpLooksLikePlanes( mod_base, &header->lumps[LUMP_PLANES], false ) &&
|
||||
Mod_LumpLooksLikePlanes( mod_base, &header->lumps[LUMP_ENTITIES], false ))
|
||||
{
|
||||
// blue-shift swapped lumps
|
||||
srclumps[0].lumpnumber = LUMP_PLANES;
|
||||
srclumps[1].lumpnumber = LUMP_ENTITIES;
|
||||
}
|
||||
else
|
||||
{
|
||||
// everything else
|
||||
srclumps[0].lumpnumber = LUMP_ENTITIES;
|
||||
srclumps[1].lumpnumber = LUMP_PLANES;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// everything else
|
||||
srclumps[0].lumpnumber = LUMP_ENTITIES;
|
||||
srclumps[1].lumpnumber = LUMP_PLANES;
|
||||
}
|
||||
|
||||
// loading base lumps
|
||||
for( i = 0; i < ARRAYSIZE( srclumps ); i++ )
|
||||
Mod_LoadLump( mod_base, &srclumps[i], &worldstats[i], isworld ? (LUMP_SAVESTATS|LUMP_SILENT) : 0 );
|
||||
@ -2907,14 +2874,42 @@ qboolean Mod_LoadBmodelLumps( const byte *mod_base, qboolean isworld )
|
||||
return true;
|
||||
}
|
||||
|
||||
static int Mod_LumpLooksLikeEntitiesFile( file_t *f, dlump_t *l, int flags, const char *msg )
|
||||
{
|
||||
char *buf;
|
||||
int ret;
|
||||
|
||||
if( FS_Seek( f, l->fileofs, SEEK_SET ) < 0 )
|
||||
{
|
||||
if( !FBitSet( flags, LUMP_SILENT ))
|
||||
Con_DPrintf( S_ERROR "map ^2%s^7 %s lump past end of file\n", loadstat.name, msg );
|
||||
return -1;
|
||||
}
|
||||
|
||||
buf = Z_Malloc( l->filelen + 1 );
|
||||
if( FS_Read( f, buf, l->filelen ) != l->filelen )
|
||||
{
|
||||
if( !FBitSet( flags, LUMP_SILENT ))
|
||||
Con_DPrintf( S_ERROR "can't read %s lump of map ^2%s^7", msg, loadstat.name );
|
||||
Z_Free( buf );
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = Mod_LumpLooksLikeEntities( buf, l->filelen );
|
||||
|
||||
Z_Free( buf );
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Mod_TestBmodelLumps
|
||||
|
||||
check for possible errors
|
||||
return real entities lump (for bshift swapped lumps)
|
||||
=================
|
||||
*/
|
||||
qboolean Mod_TestBmodelLumps( const char *name, const byte *mod_base, qboolean silent )
|
||||
qboolean Mod_TestBmodelLumps( file_t *f, const char *name, const byte *mod_base, qboolean silent, dlump_t *entities )
|
||||
{
|
||||
dheader_t *header = (dheader_t *)mod_base;
|
||||
int i, flags = LUMP_TESTONLY;
|
||||
@ -2934,11 +2929,42 @@ qboolean Mod_TestBmodelLumps( const char *name, const byte *mod_base, qboolean s
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
switch( header->version )
|
||||
{
|
||||
case Q1BSP_VERSION:
|
||||
case HLBSP_VERSION:
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = Mod_LumpLooksLikeEntitiesFile( f, &header->lumps[LUMP_ENTITIES], flags, "entities" );
|
||||
if( ret < 0 )
|
||||
return false;
|
||||
|
||||
if( !ret )
|
||||
{
|
||||
ret = Mod_LumpLooksLikeEntitiesFile( f, &header->lumps[LUMP_PLANES], flags, "planes" );
|
||||
if( ret < 0 )
|
||||
return false;
|
||||
|
||||
if( ret )
|
||||
{
|
||||
// blue-shift swapped lumps
|
||||
*entities = header->lumps[LUMP_PLANES];
|
||||
|
||||
srclumps[0].lumpnumber = LUMP_PLANES;
|
||||
srclumps[1].lumpnumber = LUMP_ENTITIES;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// intended fallthrough
|
||||
case Q1BSP_VERSION:
|
||||
case QBSP2_VERSION:
|
||||
// everything else
|
||||
*entities = header->lumps[LUMP_ENTITIES];
|
||||
|
||||
srclumps[0].lumpnumber = LUMP_ENTITIES;
|
||||
srclumps[1].lumpnumber = LUMP_PLANES;
|
||||
break;
|
||||
default:
|
||||
// don't early out: let me analyze errors
|
||||
@ -2948,30 +2974,6 @@ qboolean Mod_TestBmodelLumps( const char *name, const byte *mod_base, qboolean s
|
||||
break;
|
||||
}
|
||||
|
||||
if( header->version == HLBSP_VERSION )
|
||||
{
|
||||
// only relevant for half-life maps
|
||||
if( Mod_LumpLooksLikePlanes( mod_base, &header->lumps[LUMP_ENTITIES], true ) &&
|
||||
!Mod_LumpLooksLikePlanes( mod_base, &header->lumps[LUMP_PLANES], true ))
|
||||
{
|
||||
// blue-shift swapped lumps
|
||||
srclumps[0].lumpnumber = LUMP_PLANES;
|
||||
srclumps[1].lumpnumber = LUMP_ENTITIES;
|
||||
}
|
||||
else
|
||||
{
|
||||
// everything else
|
||||
srclumps[0].lumpnumber = LUMP_ENTITIES;
|
||||
srclumps[1].lumpnumber = LUMP_PLANES;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// everything else
|
||||
srclumps[0].lumpnumber = LUMP_ENTITIES;
|
||||
srclumps[1].lumpnumber = LUMP_PLANES;
|
||||
}
|
||||
|
||||
// loading base lumps
|
||||
for( i = 0; i < ARRAYSIZE( srclumps ); i++ )
|
||||
Mod_LoadLump( mod_base, &srclumps[i], &worldstats[i], flags );
|
||||
|
@ -148,7 +148,7 @@ void Mod_FreeUnused( void );
|
||||
// mod_bmodel.c
|
||||
//
|
||||
void Mod_LoadBrushModel( model_t *mod, const void *buffer, qboolean *loaded );
|
||||
qboolean Mod_TestBmodelLumps( const char *name, const byte *mod_base, qboolean silent );
|
||||
qboolean Mod_TestBmodelLumps( file_t *f, const char *name, const byte *mod_base, qboolean silent, dlump_t *entities );
|
||||
qboolean Mod_HeadnodeVisible( mnode_t *node, const byte *visbits, int *lastleaf );
|
||||
int Mod_FatPVS( const vec3_t org, float radius, byte *visbuffer, int visbytes, qboolean merge, qboolean fullvis );
|
||||
qboolean Mod_BoxVisible( const vec3_t mins, const vec3_t maxs, const byte *visbits );
|
||||
|
@ -849,6 +849,7 @@ void SV_WriteEntityPatch( const char *filename )
|
||||
byte buf[MAX_TOKEN]; // 1 kb
|
||||
string bspfilename;
|
||||
dheader_t *header;
|
||||
dlump_t entities;
|
||||
file_t *f;
|
||||
|
||||
Q_snprintf( bspfilename, sizeof( bspfilename ), "maps/%s.bsp", filename );
|
||||
@ -861,14 +862,14 @@ void SV_WriteEntityPatch( const char *filename )
|
||||
header = (dheader_t *)buf;
|
||||
|
||||
// check all the lumps and some other errors
|
||||
if( !Mod_TestBmodelLumps( bspfilename, buf, true ))
|
||||
if( !Mod_TestBmodelLumps( f, bspfilename, buf, true, &entities ))
|
||||
{
|
||||
FS_Close( f );
|
||||
return;
|
||||
}
|
||||
|
||||
lumpofs = header->lumps[LUMP_ENTITIES].fileofs;
|
||||
lumplen = header->lumps[LUMP_ENTITIES].filelen;
|
||||
lumpofs = entities.fileofs;
|
||||
lumplen = entities.filelen;
|
||||
|
||||
if( lumplen >= 10 )
|
||||
{
|
||||
@ -899,6 +900,7 @@ static char *SV_ReadEntityScript( const char *filename, int *flags )
|
||||
byte buf[MAX_TOKEN];
|
||||
char *ents = NULL;
|
||||
dheader_t *header;
|
||||
dlump_t entities;
|
||||
size_t ft1, ft2;
|
||||
file_t *f;
|
||||
|
||||
@ -915,7 +917,7 @@ static char *SV_ReadEntityScript( const char *filename, int *flags )
|
||||
header = (dheader_t *)buf;
|
||||
|
||||
// check all the lumps and some other errors
|
||||
if( !Mod_TestBmodelLumps( bspfilename, buf, (host_developer.value) ? false : true ))
|
||||
if( !Mod_TestBmodelLumps( f, bspfilename, buf, (host_developer.value) ? false : true, &entities ))
|
||||
{
|
||||
SetBits( *flags, MAP_INVALID_VERSION );
|
||||
FS_Close( f );
|
||||
@ -923,8 +925,8 @@ static char *SV_ReadEntityScript( const char *filename, int *flags )
|
||||
}
|
||||
|
||||
// after call Mod_TestBmodelLumps we gurantee what map is valid
|
||||
lumpofs = header->lumps[LUMP_ENTITIES].fileofs;
|
||||
lumplen = header->lumps[LUMP_ENTITIES].filelen;
|
||||
lumpofs = entities.fileofs;
|
||||
lumplen = entities.filelen;
|
||||
|
||||
// check for entfile too
|
||||
Q_snprintf( entfilename, sizeof( entfilename ), "maps/%s.ent", filename );
|
||||
|
Loading…
Reference in New Issue
Block a user