MD5: Fix uninitialized pointer dereference for file with invalid vertex index (#6439)

A segmentation fault occurred while parsing an MD5 file that contains an invalid vertex index.
The issue was caused by mScene->mMaterials not being kept in sync with mScene->mNumMaterials.
As a result, the aiScene destructor could call delete on uninitialized pointers. This patch
ensures that mScene->mNumMaterials always matches the actual contents of the mScene->mMaterials
array. That way, if an exception is thrown during file import, delete is only called for
properly allocated aiMaterial objects.
This commit is contained in:
tyler92
2026-01-12 16:08:31 +02:00
committed by GitHub
parent 522c703bb9
commit 1ce99b9cf7

View File

@@ -361,19 +361,19 @@ void MD5Importer::LoadMD5MeshFile() {
#else #else
// FIX: MD5 files exported from Blender can have empty meshes // FIX: MD5 files exported from Blender can have empty meshes
unsigned int numMaterials = 0;
for (std::vector<MD5::MeshDesc>::const_iterator it = meshParser.mMeshes.begin(), end = meshParser.mMeshes.end(); it != end; ++it) { for (std::vector<MD5::MeshDesc>::const_iterator it = meshParser.mMeshes.begin(), end = meshParser.mMeshes.end(); it != end; ++it) {
if (!(*it).mFaces.empty() && !(*it).mVertices.empty()) { if (!(*it).mFaces.empty() && !(*it).mVertices.empty()) {
++mScene->mNumMaterials; ++numMaterials;
} }
} }
// generate all meshes // generate all meshes
mScene->mNumMeshes = mScene->mNumMaterials; mScene->mMeshes = new aiMesh *[numMaterials];
mScene->mMeshes = new aiMesh *[mScene->mNumMeshes]; mScene->mMaterials = new aiMaterial *[numMaterials];
mScene->mMaterials = new aiMaterial *[mScene->mNumMeshes];
// storage for node mesh indices // storage for node mesh indices
pcNode->mNumMeshes = mScene->mNumMeshes; pcNode->mNumMeshes = numMaterials;
pcNode->mMeshes = new unsigned int[pcNode->mNumMeshes]; pcNode->mMeshes = new unsigned int[pcNode->mNumMeshes];
for (unsigned int m = 0; m < pcNode->mNumMeshes; ++m) { for (unsigned int m = 0; m < pcNode->mNumMeshes; ++m) {
pcNode->mMeshes[m] = m; pcNode->mMeshes[m] = m;
@@ -386,7 +386,10 @@ void MD5Importer::LoadMD5MeshFile() {
continue; continue;
} }
aiMesh *mesh = mScene->mMeshes[n] = new aiMesh(); aiMesh* mesh = new aiMesh();
mScene->mMeshes[n] = mesh;
++mScene->mNumMeshes;
mesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE; mesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
// generate unique vertices in our internal verbose format // generate unique vertices in our internal verbose format
@@ -508,6 +511,7 @@ void MD5Importer::LoadMD5MeshFile() {
// generate a material for the mesh // generate a material for the mesh
aiMaterial *mat = new aiMaterial(); aiMaterial *mat = new aiMaterial();
mScene->mMaterials[n] = mat; mScene->mMaterials[n] = mat;
++mScene->mNumMaterials;
// insert the typical doom3 textures: // insert the typical doom3 textures:
// nnn_local.tga - normal map // nnn_local.tga - normal map