From e32470280dc6cad684b9412109c00eed635a6e1e Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Thu, 27 Nov 2025 19:26:36 +0500 Subject: [PATCH] engine: add file size argument to brush model loading functions --- engine/common/con_utils.c | 31 ++++++++++++++-------------- engine/common/mod_bmodel.c | 21 +++++++++++-------- engine/common/mod_local.h | 4 ++-- engine/common/model.c | 2 +- engine/server/sv_game.c | 42 ++++++++++++++++++++------------------ 5 files changed, 53 insertions(+), 47 deletions(-) diff --git a/engine/common/con_utils.c b/engine/common/con_utils.c index 06cea9db..7f3ff54f 100644 --- a/engine/common/con_utils.c +++ b/engine/common/con_utils.c @@ -55,7 +55,6 @@ Cmd_ListMaps */ int Cmd_ListMaps( search_t *t, char *lastmapname, size_t len ) { - byte buf[MAX_SYSPATH]; // 1 kb file_t *f; int i, nummaps; string mapname, message, compiler, generator; @@ -78,24 +77,26 @@ int Cmd_ListMaps( search_t *t, char *lastmapname, size_t len ) if( f ) { - dheader_t *header; - dextrahdr_t *hdrext; - dlump_t entities; + dheader_t *header; + dextrahdr_t *hdrext; + dlump_t entities; + fs_offset_t filelen; + byte buf[MAX_SYSPATH] = { 0 }; // 1 kb - memset( buf, 0, sizeof( buf )); - FS_Read( f, buf, sizeof( buf )); - header = (dheader_t *)buf; - ver = header->version; + filelen = FS_Read( f, buf, sizeof( buf )); // check all the lumps and some other errors - if( Mod_TestBmodelLumps( f, t->filenames[i], buf, true, &entities )) + if( Mod_TestBmodelLumps( f, t->filenames[i], buf, filelen, true, &entities )) { lumpofs = entities.fileofs; lumplen = entities.filelen; ver = header->version; } + header = (dheader_t *)buf; hdrext = (dextrahdr_t *)((byte *)buf + sizeof( dheader_t )); + + ver = header->version; if( hdrext->id == IDEXTRAHEADER ) version = hdrext->version; Q_strncpy( entfilename, t->filenames[i], sizeof( entfilename )); @@ -892,7 +893,6 @@ static qboolean Cmd_GetCDList( const char *s, char *completedname, int length ) static qboolean Cmd_CheckMapsList_R( qboolean fRefresh, qboolean onlyingamedir ) { qboolean use_filter = false; - byte buf[MAX_SYSPATH]; string mpfilter; char *buffer; size_t buffersize; @@ -939,14 +939,15 @@ static qboolean Cmd_CheckMapsList_R( qboolean fRefresh, qboolean onlyingamedir ) if( f ) { - qboolean have_spawnpoints = false; - dlump_t entities; + qboolean have_spawnpoints = false; + dlump_t entities; + fs_offset_t filelen; + byte buf[MAX_SYSPATH] = { 0 }; - memset( buf, 0, MAX_SYSPATH ); - FS_Read( f, buf, MAX_SYSPATH ); + filelen = FS_Read( f, buf, MAX_SYSPATH ); // check all the lumps and some other errors - if( !Mod_TestBmodelLumps( f, t->filenames[i], buf, true, &entities )) + if( !Mod_TestBmodelLumps( f, t->filenames[i], buf, filelen, true, &entities )) { FS_Close( f ); continue; diff --git a/engine/common/mod_bmodel.c b/engine/common/mod_bmodel.c index 99bc60a9..22b61c6a 100644 --- a/engine/common/mod_bmodel.c +++ b/engine/common/mod_bmodel.c @@ -3674,10 +3674,10 @@ Mod_LoadBmodelLumps loading and processing bmodel ================= */ -static qboolean Mod_LoadBmodelLumps( model_t *mod, const byte *mod_base, qboolean isworld ) +static qboolean Mod_LoadBmodelLumps( model_t *mod, byte *mod_base, size_t bufferlen, qboolean isworld ) { - const dheader_t *header = (const dheader_t *)mod_base; - const dextrahdr_t *extrahdr = (const dextrahdr_t *)(mod_base + sizeof( dheader_t )); + dheader_t *header = (dheader_t *)mod_base; + dextrahdr_t *extrahdr = (dextrahdr_t *)(mod_base + sizeof( dheader_t )); dbspmodel_t *bmod = &srcmodel; char wadvalue[2048]; size_t len = 0; @@ -3842,10 +3842,10 @@ check for possible errors return real entities lump (for bshift swapped lumps) ================= */ -qboolean Mod_TestBmodelLumps( file_t *f, const char *name, const byte *mod_base, qboolean silent, dlump_t *entities ) +qboolean Mod_TestBmodelLumps( file_t *f, const char *name, byte *mod_base, size_t buffersize, qboolean silent, dlump_t *entities ) { - const dheader_t *header = (const dheader_t *)mod_base; - const dextrahdr_t *extrahdr = (const dextrahdr_t *)( mod_base + sizeof( dheader_t )); + dheader_t *header = (dheader_t *)mod_base; + dextrahdr_t *extrahdr = (dextrahdr_t *)( mod_base + sizeof( dheader_t )); int i, flags = LUMP_TESTONLY; // always reset the intermediate struct @@ -3856,10 +3856,13 @@ qboolean Mod_TestBmodelLumps( file_t *f, const char *name, const byte *mod_base, if( silent ) SetBits( flags, LUMP_SILENT ); + if( buffersize < sizeof( *header )) + return false; + switch( header->version ) { case HLBSP_VERSION: - if( extrahdr->id == IDEXTRAHEADER ) + if( buffersize > sizeof( *header ) + sizeof( *extrahdr ) && extrahdr->id == IDEXTRAHEADER ) { SetBits( flags, LUMP_BSP30EXT ); } @@ -3928,7 +3931,7 @@ qboolean Mod_TestBmodelLumps( file_t *f, const char *name, const byte *mod_base, Mod_LoadBrushModel ================= */ -void Mod_LoadBrushModel( model_t *mod, const void *buffer, qboolean *loaded ) +void Mod_LoadBrushModel( model_t *mod, void *buffer, size_t buffersize, qboolean *loaded ) { char poolname[MAX_VA_STRING]; @@ -3940,7 +3943,7 @@ void Mod_LoadBrushModel( model_t *mod, const void *buffer, qboolean *loaded ) mod->type = mod_brush; // loading all the lumps into heap - if( !Mod_LoadBmodelLumps( mod, buffer, world.loading )) + if( !Mod_LoadBmodelLumps( mod, buffer, buffersize, world.loading )) return; // there were errors if( world.loading ) worldmodel = mod; diff --git a/engine/common/mod_local.h b/engine/common/mod_local.h index 464bc541..0f1778aa 100644 --- a/engine/common/mod_local.h +++ b/engine/common/mod_local.h @@ -167,8 +167,8 @@ void Mod_LoadAliasModel( model_t *mod, const void *buffer, qboolean *loaded ); // // mod_bmodel.c // -void Mod_LoadBrushModel( model_t *mod, const void *buffer, qboolean *loaded ); -qboolean Mod_TestBmodelLumps( file_t *f, const char *name, const byte *mod_base, qboolean silent, dlump_t *entities ); +void Mod_LoadBrushModel( model_t *mod, void *buffer, size_t buffersize, qboolean *loaded ); +qboolean Mod_TestBmodelLumps( file_t *f, const char *name, byte *mod_base, size_t buffersize, qboolean silent, dlump_t *entities ); int Mod_FatPVS( const vec3_t org, float radius, byte *visbuffer, int visbytes, qboolean merge, qboolean fullvis, qboolean phs ); qboolean Mod_BoxVisible( const vec3_t mins, const vec3_t maxs, const byte *visbits ); int Mod_CheckLump( const char *filename, const int lump, int *lumpsize ); diff --git a/engine/common/model.c b/engine/common/model.c index 1e4a9d6c..1829c6ff 100644 --- a/engine/common/model.c +++ b/engine/common/model.c @@ -310,7 +310,7 @@ model_t *Mod_LoadModel( model_t *mod, qboolean crash ) case LittleLong( Q1BSP_VERSION ): case LittleLong( HLBSP_VERSION ): case LittleLong( QBSP2_VERSION ): - Mod_LoadBrushModel( mod, buf, &loaded ); + Mod_LoadBrushModel( mod, buf, length, &loaded ); break; default: Mem_Free( buf ); diff --git a/engine/server/sv_game.c b/engine/server/sv_game.c index 44248591..70359d39 100644 --- a/engine/server/sv_game.c +++ b/engine/server/sv_game.c @@ -805,22 +805,23 @@ Create entity patch for selected map */ void SV_WriteEntityPatch( const char *filename ) { - int lumpofs = 0, lumplen = 0; - byte buf[MAX_TOKEN]; // 1 kb - string bspfilename; - dlump_t entities; - file_t *f; + int lumpofs = 0, lumplen = 0; + byte buf[MAX_TOKEN] = { 0 }; // 1 kb + string bspfilename; + dlump_t entities; + file_t *f; + fs_offset_t filelen; Q_snprintf( bspfilename, sizeof( bspfilename ), "maps/%s.bsp", filename ); f = FS_Open( bspfilename, "rb", false ); - if( !f ) return; + if( !f ) + return; - memset( buf, 0, MAX_TOKEN ); - FS_Read( f, buf, MAX_TOKEN ); + filelen = FS_Read( f, buf, MAX_TOKEN ); // check all the lumps and some other errors - if( !Mod_TestBmodelLumps( f, bspfilename, buf, true, &entities )) + if( !Mod_TestBmodelLumps( f, bspfilename, buf, filelen, true, &entities )) { FS_Close( f ); return; @@ -853,27 +854,28 @@ pfnMapIsValid use this */ static char *SV_ReadEntityScript( const char *filename, int *flags ) { - string bspfilename, entfilename; - int lumpofs = 0, lumplen = 0; - byte buf[MAX_TOKEN]; - char *ents = NULL; - dlump_t entities; - size_t ft1, ft2; - file_t *f; + string bspfilename, entfilename; + int lumpofs = 0, lumplen = 0; + byte buf[MAX_TOKEN] = { 0 }; + char *ents = NULL; + dlump_t entities; + size_t ft1, ft2; + file_t *f; + fs_offset_t filelen; *flags = 0; Q_snprintf( bspfilename, sizeof( bspfilename ), "maps/%s.bsp", filename ); f = FS_Open( bspfilename, "rb", false ); - if( !f ) return NULL; + if( !f ) + return NULL; SetBits( *flags, MAP_IS_EXIST ); - memset( buf, 0, MAX_TOKEN ); - FS_Read( f, buf, MAX_TOKEN ); + filelen = FS_Read( f, buf, sizeof( buf )); // check all the lumps and some other errors - if( !Mod_TestBmodelLumps( f, bspfilename, buf, (host_developer.value) ? false : true, &entities )) + if( !Mod_TestBmodelLumps( f, bspfilename, buf, filelen, (host_developer.value) ? false : true, &entities )) { SetBits( *flags, MAP_INVALID_VERSION ); FS_Close( f );