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:
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user