From 3e188e6768739d48a58465fdbf339674c4bc70de Mon Sep 17 00:00:00 2001 From: Oliver Chang Date: Mon, 23 Feb 2026 07:27:05 +1100 Subject: [PATCH] HL1MDLLoader: fix segfault in destructors (#6537) In `HL1MDLLoader::read_animations`, the arrays for `scene_->mAnimations` and `scene_animation->mChannels` were allocated using `new T*[count]`. This performs default initialization, which leaves the pointer elements with indeterminate (garbage) values. If an exception (such as a `DeadlyImportError` from malformed input) is thrown during the loop populating these arrays, the `aiScene` or `aiAnimation` destructors are invoked during stack unwinding. These destructors iterate through the allocated arrays and call `delete` on each element. Because the arrays contained garbage values for indices not yet reached by the loader, the destructor attempted to delete invalid memory addresses, leading to a segmentation fault. This patch changes the allocations to use value-initialization (`new T*[count]()`), ensuring all pointers are initialized to `nullptr`. Since `delete nullptr` is a safe no-op, the destructors can now safely clean up partially initialized objects during an exception. Fixes: https://issues.oss-fuzz.com/issues/483188619 Co-authored-by: CodeMender Co-authored-by: Kim Kulling --- code/AssetLib/MDL/HalfLife/HL1MDLLoader.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/AssetLib/MDL/HalfLife/HL1MDLLoader.cpp b/code/AssetLib/MDL/HalfLife/HL1MDLLoader.cpp index 3949f76a2..e2dce6cf9 100644 --- a/code/AssetLib/MDL/HalfLife/HL1MDLLoader.cpp +++ b/code/AssetLib/MDL/HalfLife/HL1MDLLoader.cpp @@ -971,7 +971,7 @@ void HL1MDLLoader::read_animations() { pseqdesc = get_buffer_data(header_->seqindex, header_->numseq); - aiAnimation **scene_animations_ptr = scene_->mAnimations = new aiAnimation *[scene_->mNumAnimations]; + aiAnimation **scene_animations_ptr = scene_->mAnimations = new aiAnimation *[scene_->mNumAnimations](); for (int sequence = 0; sequence < header_->numseq; ++sequence, ++pseqdesc) { pseqgroup = get_buffer_data(header_->seqgroupindex + pseqdesc->seqgroup * sizeof(SequenceGroup_HL1), 1); @@ -992,7 +992,7 @@ void HL1MDLLoader::read_animations() { scene_animation->mTicksPerSecond = pseqdesc->fps; scene_animation->mDuration = static_cast(pseqdesc->fps) * pseqdesc->numframes; scene_animation->mNumChannels = static_cast(header_->numbones); - scene_animation->mChannels = new aiNodeAnim *[scene_animation->mNumChannels]; + scene_animation->mChannels = new aiNodeAnim *[scene_animation->mNumChannels](); for (int bone = 0; bone < header_->numbones; bone++, ++pbone, ++panim) { aiNodeAnim *node_anim = scene_animation->mChannels[bone] = new aiNodeAnim();