Merge pull request #2927 from malortie/mdl-fix-buffer-memory-leak

Fixed memory leak in MDL importer.
pull/2910/head^2
Kim Kulling 2020-01-19 12:19:53 +01:00 committed by GitHub
commit 8177706716
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 89 additions and 78 deletions

View File

@ -185,87 +185,98 @@ void MDLImporter::InternReadFile( const std::string& pFile,
throw DeadlyImportError( "MDL File is too small."); throw DeadlyImportError( "MDL File is too small.");
} }
// Allocate storage and copy the contents of the file to a memory buffer // delete the file buffer and cleanup.
mBuffer =new unsigned char[iFileSize+1]; auto DeleteBufferAndCleanup = [&]() {
file->Read( (void*)mBuffer, 1, iFileSize); if (mBuffer) {
delete [] mBuffer;
// Append a binary zero to the end of the buffer. mBuffer = nullptr;
// this is just for safety that string parsing routines
// find the end of the buffer ...
mBuffer[iFileSize] = '\0';
const uint32_t iMagicWord = *((uint32_t*)mBuffer);
// Determine the file subtype and call the appropriate member function
// Original Quake1 format
if (AI_MDL_MAGIC_NUMBER_BE == iMagicWord || AI_MDL_MAGIC_NUMBER_LE == iMagicWord) {
ASSIMP_LOG_DEBUG("MDL subtype: Quake 1, magic word is IDPO");
iGSFileVersion = 0;
InternReadFile_Quake1();
}
// GameStudio A<old> MDL2 format - used by some test models that come with 3DGS
else if (AI_MDL_MAGIC_NUMBER_BE_GS3 == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS3 == iMagicWord) {
ASSIMP_LOG_DEBUG("MDL subtype: 3D GameStudio A2, magic word is MDL2");
iGSFileVersion = 2;
InternReadFile_Quake1();
}
// GameStudio A4 MDL3 format
else if (AI_MDL_MAGIC_NUMBER_BE_GS4 == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS4 == iMagicWord) {
ASSIMP_LOG_DEBUG("MDL subtype: 3D GameStudio A4, magic word is MDL3");
iGSFileVersion = 3;
InternReadFile_3DGS_MDL345();
}
// GameStudio A5+ MDL4 format
else if (AI_MDL_MAGIC_NUMBER_BE_GS5a == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS5a == iMagicWord) {
ASSIMP_LOG_DEBUG("MDL subtype: 3D GameStudio A4, magic word is MDL4");
iGSFileVersion = 4;
InternReadFile_3DGS_MDL345();
}
// GameStudio A5+ MDL5 format
else if (AI_MDL_MAGIC_NUMBER_BE_GS5b == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS5b == iMagicWord) {
ASSIMP_LOG_DEBUG("MDL subtype: 3D GameStudio A5, magic word is MDL5");
iGSFileVersion = 5;
InternReadFile_3DGS_MDL345();
}
// GameStudio A7 MDL7 format
else if (AI_MDL_MAGIC_NUMBER_BE_GS7 == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS7 == iMagicWord) {
ASSIMP_LOG_DEBUG("MDL subtype: 3D GameStudio A7, magic word is MDL7");
iGSFileVersion = 7;
InternReadFile_3DGS_MDL7();
}
// IDST/IDSQ Format (CS:S/HL^2, etc ...)
else if (AI_MDL_MAGIC_NUMBER_BE_HL2a == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_HL2a == iMagicWord ||
AI_MDL_MAGIC_NUMBER_BE_HL2b == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_HL2b == iMagicWord)
{
iGSFileVersion = 0;
HalfLife::HalfLifeMDLBaseHeader *pHeader = (HalfLife::HalfLifeMDLBaseHeader *)mBuffer;
if (pHeader->version == AI_MDL_HL1_VERSION)
{
ASSIMP_LOG_DEBUG("MDL subtype: Half-Life 1/Goldsrc Engine, magic word is IDST/IDSQ");
InternReadFile_HL1(pFile, iMagicWord);
} }
else AI_DEBUG_INVALIDATE_PTR(pIOHandler);
{ AI_DEBUG_INVALIDATE_PTR(pScene);
ASSIMP_LOG_DEBUG("MDL subtype: Source(tm) Engine, magic word is IDST/IDSQ"); };
InternReadFile_HL2();
try {
// Allocate storage and copy the contents of the file to a memory buffer
mBuffer = new unsigned char[iFileSize+1];
file->Read( (void*)mBuffer, 1, iFileSize);
// Append a binary zero to the end of the buffer.
// this is just for safety that string parsing routines
// find the end of the buffer ...
mBuffer[iFileSize] = '\0';
const uint32_t iMagicWord = *((uint32_t*)mBuffer);
// Determine the file subtype and call the appropriate member function
// Original Quake1 format
if (AI_MDL_MAGIC_NUMBER_BE == iMagicWord || AI_MDL_MAGIC_NUMBER_LE == iMagicWord) {
ASSIMP_LOG_DEBUG("MDL subtype: Quake 1, magic word is IDPO");
iGSFileVersion = 0;
InternReadFile_Quake1();
} }
} // GameStudio A<old> MDL2 format - used by some test models that come with 3DGS
else { else if (AI_MDL_MAGIC_NUMBER_BE_GS3 == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS3 == iMagicWord) {
// print the magic word to the log file ASSIMP_LOG_DEBUG("MDL subtype: 3D GameStudio A2, magic word is MDL2");
throw DeadlyImportError( "Unknown MDL subformat " + pFile + iGSFileVersion = 2;
". Magic word (" + std::string((char*)&iMagicWord,4) + ") is not known"); InternReadFile_Quake1();
} }
// GameStudio A4 MDL3 format
else if (AI_MDL_MAGIC_NUMBER_BE_GS4 == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS4 == iMagicWord) {
ASSIMP_LOG_DEBUG("MDL subtype: 3D GameStudio A4, magic word is MDL3");
iGSFileVersion = 3;
InternReadFile_3DGS_MDL345();
}
// GameStudio A5+ MDL4 format
else if (AI_MDL_MAGIC_NUMBER_BE_GS5a == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS5a == iMagicWord) {
ASSIMP_LOG_DEBUG("MDL subtype: 3D GameStudio A4, magic word is MDL4");
iGSFileVersion = 4;
InternReadFile_3DGS_MDL345();
}
// GameStudio A5+ MDL5 format
else if (AI_MDL_MAGIC_NUMBER_BE_GS5b == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS5b == iMagicWord) {
ASSIMP_LOG_DEBUG("MDL subtype: 3D GameStudio A5, magic word is MDL5");
iGSFileVersion = 5;
InternReadFile_3DGS_MDL345();
}
// GameStudio A7 MDL7 format
else if (AI_MDL_MAGIC_NUMBER_BE_GS7 == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS7 == iMagicWord) {
ASSIMP_LOG_DEBUG("MDL subtype: 3D GameStudio A7, magic word is MDL7");
iGSFileVersion = 7;
InternReadFile_3DGS_MDL7();
}
// IDST/IDSQ Format (CS:S/HL^2, etc ...)
else if (AI_MDL_MAGIC_NUMBER_BE_HL2a == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_HL2a == iMagicWord ||
AI_MDL_MAGIC_NUMBER_BE_HL2b == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_HL2b == iMagicWord)
{
iGSFileVersion = 0;
// Now rotate the whole scene 90 degrees around the x axis to convert to internal coordinate system HalfLife::HalfLifeMDLBaseHeader *pHeader = (HalfLife::HalfLifeMDLBaseHeader *)mBuffer;
pScene->mRootNode->mTransformation = aiMatrix4x4(1.f,0.f,0.f,0.f, if (pHeader->version == AI_MDL_HL1_VERSION)
0.f,0.f,1.f,0.f,0.f,-1.f,0.f,0.f,0.f,0.f,0.f,1.f); {
ASSIMP_LOG_DEBUG("MDL subtype: Half-Life 1/Goldsrc Engine, magic word is IDST/IDSQ");
InternReadFile_HL1(pFile, iMagicWord);
}
else
{
ASSIMP_LOG_DEBUG("MDL subtype: Source(tm) Engine, magic word is IDST/IDSQ");
InternReadFile_HL2();
}
}
else {
// print the magic word to the log file
throw DeadlyImportError( "Unknown MDL subformat " + pFile +
". Magic word (" + std::string((char*)&iMagicWord,4) + ") is not known");
}
// delete the file buffer and cleanup // Now rotate the whole scene 90 degrees around the x axis to convert to internal coordinate system
delete [] mBuffer; pScene->mRootNode->mTransformation = aiMatrix4x4(1.f,0.f,0.f,0.f,
mBuffer= nullptr; 0.f,0.f,1.f,0.f,0.f,-1.f,0.f,0.f,0.f,0.f,0.f,1.f);
AI_DEBUG_INVALIDATE_PTR(pIOHandler);
AI_DEBUG_INVALIDATE_PTR(pScene); DeleteBufferAndCleanup();
} catch(...) {
DeleteBufferAndCleanup();
throw;
}
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------