fix issue #5461 (segfault after removing redundant materials) (#5467)

* fix issue #5641 (segfault after removing redundant materials)

* Update RemoveRedundantMaterials.cpp

- Fix 2 possible memleaks.

---------

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
pull/5382/head
Stephen Gold 2024-04-09 15:22:57 -07:00 committed by GitHub
parent 3ff7851ff9
commit 08c1adc015
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 9 additions and 9 deletions

View File

@ -81,27 +81,26 @@ void RemoveRedundantMatsProcess::Execute( aiScene* pScene) {
// Find out which materials are referenced by meshes // Find out which materials are referenced by meshes
std::vector<bool> abReferenced(pScene->mNumMaterials,false); std::vector<bool> abReferenced(pScene->mNumMaterials,false);
for (unsigned int i = 0;i < pScene->mNumMeshes;++i) for (unsigned int i = 0;i < pScene->mNumMeshes;++i) {
abReferenced[pScene->mMeshes[i]->mMaterialIndex] = true; abReferenced[pScene->mMeshes[i]->mMaterialIndex] = true;
}
// If a list of materials to be excluded was given, match the list with // If a list of materials to be excluded was given, match the list with
// our imported materials and 'salt' all positive matches to ensure that // our imported materials and 'salt' all positive matches to ensure that
// we get unique hashes later. // we get unique hashes later.
if (mConfigFixedMaterials.length()) { if (mConfigFixedMaterials.length()) {
std::list<std::string> strings; std::list<std::string> strings;
ConvertListToStrings(mConfigFixedMaterials,strings); ConvertListToStrings(mConfigFixedMaterials,strings);
for (unsigned int i = 0; i < pScene->mNumMaterials;++i) { for (unsigned int i = 0; i < pScene->mNumMaterials;++i) {
aiMaterial* mat = pScene->mMaterials[i]; aiMaterial* mat = pScene->mMaterials[i];
ai_assert(mat != nullptr);
aiString name; aiString name;
mat->Get(AI_MATKEY_NAME,name); mat->Get(AI_MATKEY_NAME,name);
if (name.length) { if (name.length != 0) {
std::list<std::string>::const_iterator it = std::find(strings.begin(), strings.end(), name.data); std::list<std::string>::const_iterator it = std::find(strings.begin(), strings.end(), name.data);
if (it != strings.end()) { if (it != strings.end()) {
// Our brilliant 'salt': A single material property with ~ as first // Our brilliant 'salt': A single material property with ~ as first
// character to mark it as internal and temporary. // character to mark it as internal and temporary.
const int dummy = 1; const int dummy = 1;
@ -126,7 +125,7 @@ void RemoveRedundantMatsProcess::Execute( aiScene* pScene) {
// store all hashes in a list and so a quick search whether // store all hashes in a list and so a quick search whether
// we do already have a specific hash. This allows us to // we do already have a specific hash. This allows us to
// determine which materials are identical. // determine which materials are identical.
uint32_t *aiHashes = new uint32_t[ pScene->mNumMaterials ];; uint32_t *aiHashes = new uint32_t[ pScene->mNumMaterials ];
for (unsigned int i = 0; i < pScene->mNumMaterials;++i) { for (unsigned int i = 0; i < pScene->mNumMaterials;++i) {
// No mesh is referencing this material, remove it. // No mesh is referencing this material, remove it.
if (!abReferenced[i]) { if (!abReferenced[i]) {
@ -157,15 +156,16 @@ void RemoveRedundantMatsProcess::Execute( aiScene* pScene) {
// If the new material count differs from the original, // If the new material count differs from the original,
// we need to rebuild the material list and remap mesh material indexes. // we need to rebuild the material list and remap mesh material indexes.
if (iNewNum < 1) { if (iNewNum < 1) {
//throw DeadlyImportError("No materials remaining"); delete [] aiMappingTable;
delete [] aiHashes;
pScene->mNumMaterials = 0;
return; return;
} }
if (iNewNum != pScene->mNumMaterials) { if (iNewNum != pScene->mNumMaterials) {
ai_assert(iNewNum > 0); ai_assert(iNewNum > 0);
aiMaterial** ppcMaterials = new aiMaterial*[iNewNum]; aiMaterial** ppcMaterials = new aiMaterial*[iNewNum];
::memset(ppcMaterials,0,sizeof(void*)*iNewNum); ::memset(ppcMaterials,0,sizeof(void*)*iNewNum);
for (unsigned int p = 0; p < pScene->mNumMaterials;++p) for (unsigned int p = 0; p < pScene->mNumMaterials;++p) {
{
// if the material is not referenced ... remove it // if the material is not referenced ... remove it
if (!abReferenced[p]) { if (!abReferenced[p]) {
continue; continue;