From 0b0ba2ec4dd161bfe7a16e6d5133c7e285c5a242 Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Thu, 13 Aug 2015 13:01:49 +0300 Subject: [PATCH] Refactor logic which checks for too large allocations It's now easier to change the limit --- code/ACLoader.cpp | 6 +++--- code/MD3Loader.cpp | 4 +++- code/ObjFileImporter.cpp | 2 +- include/assimp/defs.h | 8 ++++++++ 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/code/ACLoader.cpp b/code/ACLoader.cpp index 8d2fac171..8e62da442 100644 --- a/code/ACLoader.cpp +++ b/code/ACLoader.cpp @@ -296,7 +296,7 @@ void AC3DImporter::LoadObjectSection(std::vector& objects) SkipSpaces(&buffer); unsigned int t = strtoul10(buffer,&buffer); - if (t >= std::numeric_limits::max() / sizeof(aiVector3D)) { + if (t >= AI_MAX_ALLOC(aiVector3D)) { throw DeadlyImportError("AC3D: Too many vertices, would run out of memory"); } obj.vertices.reserve(t); @@ -589,7 +589,7 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object, mesh->mNumFaces = (*cit).first; if (mesh->mNumFaces == 0) { throw DeadlyImportError("AC3D: No faces"); - } else if (mesh->mNumFaces > std::numeric_limits::max() / sizeof(aiFace)) { + } else if (mesh->mNumFaces > AI_MAX_ALLOC(aiFace)) { throw DeadlyImportError("AC3D: Too many faces, would run out of memory"); } aiFace* faces = mesh->mFaces = new aiFace[mesh->mNumFaces]; @@ -597,7 +597,7 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object, mesh->mNumVertices = (*cit).second; if (mesh->mNumVertices == 0) { throw DeadlyImportError("AC3D: No vertices"); - } else if (mesh->mNumVertices > std::numeric_limits::max() / sizeof(aiVector3D)) { + } else if (mesh->mNumVertices > AI_MAX_ALLOC(aiVector3D)) { throw DeadlyImportError("AC3D: Too many vertices, would run out of memory"); } aiVector3D* vertices = mesh->mVertices = new aiVector3D[mesh->mNumVertices]; diff --git a/code/MD3Loader.cpp b/code/MD3Loader.cpp index 5e9a1a3dc..3852a64a2 100644 --- a/code/MD3Loader.cpp +++ b/code/MD3Loader.cpp @@ -785,7 +785,9 @@ void MD3Importer::InternReadFile( const std::string& pFile, pScene->mNumMeshes = pcHeader->NUM_SURFACES; if (pcHeader->NUM_SURFACES == 0) { throw DeadlyImportError("MD3: No surfaces"); - } else if (pcHeader->NUM_SURFACES > std::numeric_limits::max() / sizeof(aiMesh)) { + } else if (pcHeader->NUM_SURFACES > AI_MAX_ALLOC(aiMesh)) { + // We allocate pointers but check against the size of aiMesh + // since those pointers will eventually have to point to real objects throw DeadlyImportError("MD3: Too many surfaces, would run out of memory"); } pScene->mMeshes = new aiMesh*[pScene->mNumMeshes]; diff --git a/code/ObjFileImporter.cpp b/code/ObjFileImporter.cpp index 7ade10f62..e4046b53b 100644 --- a/code/ObjFileImporter.cpp +++ b/code/ObjFileImporter.cpp @@ -382,7 +382,7 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel, pMesh->mNumVertices = numIndices; if (pMesh->mNumVertices == 0) { throw DeadlyImportError( "OBJ: no vertices" ); - } else if (pMesh->mNumVertices > std::numeric_limits::max() / sizeof(aiVector3D)) { + } else if (pMesh->mNumVertices > AI_MAX_ALLOC(aiVector3D)) { throw DeadlyImportError( "OBJ: Too many vertices, would run out of memory" ); } pMesh->mVertices = new aiVector3D[ pMesh->mNumVertices ]; diff --git a/include/assimp/defs.h b/include/assimp/defs.h index b0954920e..3129a027b 100644 --- a/include/assimp/defs.h +++ b/include/assimp/defs.h @@ -276,4 +276,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # define AI_BUILD_BIG_ENDIAN #endif + +/* To avoid running out of memory + * This can be adjusted for specific use cases + * It's NOT a total limit, just a limit for individual allocations + */ +#define AI_MAX_ALLOC(type) ((256U * 1024 * 1024) / sizeof(type)) + + #endif // !! INCLUDED_AI_DEFINES_H