Skip to content

Commit 09beb29

Browse files
committed
engine: common: mod_studio: fix model traversal and crash in Mod_StudioComputeBounds
Mod_StudioComputeBounds incorrectly assumed that all models across all body parts were laid out contiguously in memory. This caused out-of-bounds reads or reading garbage data when loading complex models, leading to crashes. Also fixed R_StudioCalcBones call to pass the animation data pointer for the current bone (&panim[j]) instead of always using the first bone's data. This ensures animation bounding boxes are calculated correctly for each bone.
1 parent 9554805 commit 09beb29

1 file changed

Lines changed: 9 additions & 12 deletions

File tree

engine/common/mod_studio.c

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -690,7 +690,6 @@ static void Mod_StudioComputeBounds( void *buffer, vec3_t mins, vec3_t maxs, qbo
690690
vec3_t bone_mins, bone_maxs;
691691
vec3_t vert_mins, vert_maxs;
692692
int vert_count, bone_count;
693-
int bodyCount = 0;
694693
vec3_t pos, *pverts;
695694

696695
vert_count = bone_count = 0;
@@ -706,18 +705,16 @@ static void Mod_StudioComputeBounds( void *buffer, vec3_t mins, vec3_t maxs, qbo
706705
// each body part has nummodels variations so there are as many total variations as there
707706
// are in a matrix of each part by each other part
708707
for( i = 0; i < pstudiohdr->numbodyparts; i++ )
709-
bodyCount += pbodypart[i].nummodels;
710-
711-
// The studio models we want are vec3_t mins, vec3_t maxsight after the bodyparts (still need to
712-
// find a detailed breakdown of the mdl format). Move pointer there.
713-
m_pSubModel = (mstudiomodel_t *)(&pbodypart[pstudiohdr->numbodyparts]);
714-
715-
for( i = 0; i < bodyCount; i++ )
716708
{
717-
pverts = (vec3_t *)((byte *)pstudiohdr + m_pSubModel[i].vertindex);
709+
m_pSubModel = (mstudiomodel_t *)((byte *)pstudiohdr + pbodypart[i].modelindex);
718710

719-
for( j = 0; j < m_pSubModel[i].numverts; j++ )
720-
Mod_StudioBoundVertex( bone_mins, bone_maxs, &vert_count, pverts[j] );
711+
for( j = 0; j < pbodypart[i].nummodels; j++ )
712+
{
713+
pverts = (vec3_t *)((byte *)pstudiohdr + m_pSubModel[j].vertindex);
714+
715+
for( k = 0; k < m_pSubModel[j].numverts; k++ )
716+
Mod_StudioBoundVertex( bone_mins, bone_maxs, &vert_count, pverts[k] );
717+
}
721718
}
722719

723720
pbones = (mstudiobone_t *)((byte *)pstudiohdr + pstudiohdr->boneindex);
@@ -736,7 +733,7 @@ static void Mod_StudioComputeBounds( void *buffer, vec3_t mins, vec3_t maxs, qbo
736733
{
737734
for( k = 0; k < pseqdesc->numframes; k++ )
738735
{
739-
R_StudioCalcBones( k, 0, &pbones[j], panim, NULL, pos, NULL );
736+
R_StudioCalcBones( k, 0, &pbones[j], &panim[j], NULL, pos, NULL );
740737
Mod_StudioBoundVertex( vert_mins, vert_maxs, &bone_count, pos );
741738
}
742739
}

0 commit comments

Comments
 (0)