Explorar el Código

Merge pull request #632 from turol/afl-fixes

Random crash fixes
Kim Kulling hace 10 años
padre
commit
4afddf316f
Se han modificado 6 ficheros con 43 adiciones y 1 borrados
  1. 14 1
      code/ACLoader.cpp
  2. 7 0
      code/MD3Loader.cpp
  3. 3 0
      code/MDLLoader.cpp
  4. 5 0
      code/ObjFileImporter.cpp
  5. 6 0
      code/STLLoader.cpp
  6. 8 0
      include/assimp/defs.h

+ 14 - 1
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<Object>& objects)
             SkipSpaces(&buffer);
 
             unsigned int t = strtoul10(buffer,&buffer);
-            if (t >= std::numeric_limits<int32_t>::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;
 

+ 7 - 0
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;

+ 3 - 0
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 );

+ 5 - 0
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

+ 6 - 0
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<float>(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());

+ 8 - 0
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