diff --git a/code/ACLoader.cpp b/code/ACLoader.cpp index dac85b8db..8e62da442 100644 --- a/code/ACLoader.cpp +++ b/code/ACLoader.cpp @@ -89,6 +89,9 @@ static const aiImporterDesc desc = { // ------------------------------------------------------------------------------------------------ // read a string (may be enclosed in double quotation marks). buffer must point to " #define AI_AC_GET_STRING(out) \ + if (*buffer == '\0') { \ + throw DeadlyImportError("AC3D: Unexpected EOF in string"); \ + } \ ++buffer; \ const char* sz = buffer; \ while ('\"' != *buffer) \ @@ -293,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); @@ -584,9 +587,19 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object, // allocate storage for vertices and normals mesh->mNumFaces = (*cit).first; + if (mesh->mNumFaces == 0) { + throw DeadlyImportError("AC3D: No faces"); + } 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]; mesh->mNumVertices = (*cit).second; + if (mesh->mNumVertices == 0) { + throw DeadlyImportError("AC3D: No vertices"); + } 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]; unsigned int cur = 0; diff --git a/code/MD3Loader.cpp b/code/MD3Loader.cpp index f7fafefdd..3852a64a2 100644 --- a/code/MD3Loader.cpp +++ b/code/MD3Loader.cpp @@ -783,6 +783,13 @@ void MD3Importer::InternReadFile( const std::string& pFile, // Allocate output storage pScene->mNumMeshes = pcHeader->NUM_SURFACES; + if (pcHeader->NUM_SURFACES == 0) { + throw DeadlyImportError("MD3: No surfaces"); + } 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]; pScene->mNumMaterials = pcHeader->NUM_SURFACES; diff --git a/code/MDLLoader.cpp b/code/MDLLoader.cpp index 60c92661b..c5b8d63c3 100644 --- a/code/MDLLoader.cpp +++ b/code/MDLLoader.cpp @@ -355,6 +355,9 @@ void MDLImporter::InternReadFile_Quake1( ) for (unsigned int i = 0; i < (unsigned int)pcHeader->num_skins;++i) { union{BE_NCONST MDL::Skin* pcSkin;BE_NCONST MDL::GroupSkin* pcGroupSkin;}; + if (szCurrent + sizeof(MDL::Skin) > this->mBuffer + this->iFileSize) { + throw DeadlyImportError("[Quake 1 MDL] Unexpected EOF"); + } pcSkin = (BE_NCONST MDL::Skin*)szCurrent; AI_SWAP4( pcSkin->group ); diff --git a/code/ObjFileImporter.cpp b/code/ObjFileImporter.cpp index 02232fcd1..e4046b53b 100644 --- a/code/ObjFileImporter.cpp +++ b/code/ObjFileImporter.cpp @@ -380,6 +380,11 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel, // Copy vertices of this mesh instance pMesh->mNumVertices = numIndices; + if (pMesh->mNumVertices == 0) { + throw DeadlyImportError( "OBJ: no vertices" ); + } 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 ]; // Allocate buffer for normal vectors diff --git a/code/STLLoader.cpp b/code/STLLoader.cpp index a9fe79f27..f840ce29c 100644 --- a/code/STLLoader.cpp +++ b/code/STLLoader.cpp @@ -303,6 +303,9 @@ void STLImporter::LoadASCIIFile() } else { + if (sz[6] == '\0') { + throw DeadlyImportError("STL: unexpected EOF while parsing facet"); + } sz += 7; SkipSpaces(&sz); sz = fast_atoreal_move(sz, (float&)vn->x ); @@ -323,6 +326,9 @@ void STLImporter::LoadASCIIFile() } else { + if (sz[6] == '\0') { + throw DeadlyImportError("STL: unexpected EOF while parsing facet"); + } sz += 7; SkipSpaces(&sz); positionBuffer.push_back(aiVector3D()); 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