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 <codemender-patching@google.com>
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
This commit is contained in:
Oliver Chang
2026-02-23 07:27:05 +11:00
committed by GitHub
parent 21607dfb75
commit 3e188e6768

View File

@@ -971,7 +971,7 @@ void HL1MDLLoader::read_animations() {
pseqdesc = get_buffer_data<SequenceDesc_HL1>(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<SequenceGroup_HL1>(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<double>(pseqdesc->fps) * pseqdesc->numframes;
scene_animation->mNumChannels = static_cast<unsigned int>(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();