瀏覽代碼

Refactor logic which checks for too large allocations

It's now easier to change the limit
Turo Lamminen 10 年之前
父節點
當前提交
0b0ba2ec4d
共有 4 個文件被更改,包括 15 次插入5 次删除
  1. 3 3
      code/ACLoader.cpp
  2. 3 1
      code/MD3Loader.cpp
  3. 1 1
      code/ObjFileImporter.cpp
  4. 8 0
      include/assimp/defs.h

+ 3 - 3
code/ACLoader.cpp

@@ -296,7 +296,7 @@ void AC3DImporter::LoadObjectSection(std::vector<Object>& objects)
             SkipSpaces(&buffer);
             SkipSpaces(&buffer);
 
 
             unsigned int t = strtoul10(buffer,&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");
                 throw DeadlyImportError("AC3D: Too many vertices, would run out of memory");
             }
             }
             obj.vertices.reserve(t);
             obj.vertices.reserve(t);
@@ -589,7 +589,7 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object,
                 mesh->mNumFaces = (*cit).first;
                 mesh->mNumFaces = (*cit).first;
                 if (mesh->mNumFaces == 0) {
                 if (mesh->mNumFaces == 0) {
                     throw DeadlyImportError("AC3D: No faces");
                     throw DeadlyImportError("AC3D: No faces");
-                } else if (mesh->mNumFaces > std::numeric_limits<int32_t>::max() / sizeof(aiFace)) {
+                } else if (mesh->mNumFaces > AI_MAX_ALLOC(aiFace)) {
                     throw DeadlyImportError("AC3D: Too many faces, would run out of memory");
                     throw DeadlyImportError("AC3D: Too many faces, would run out of memory");
                 }
                 }
                 aiFace* faces = mesh->mFaces = new aiFace[mesh->mNumFaces];
                 aiFace* faces = mesh->mFaces = new aiFace[mesh->mNumFaces];
@@ -597,7 +597,7 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object,
                 mesh->mNumVertices = (*cit).second;
                 mesh->mNumVertices = (*cit).second;
                 if (mesh->mNumVertices == 0) {
                 if (mesh->mNumVertices == 0) {
                     throw DeadlyImportError("AC3D: No vertices");
                     throw DeadlyImportError("AC3D: No vertices");
-                } else if (mesh->mNumVertices > std::numeric_limits<int32_t>::max() / sizeof(aiVector3D)) {
+                } else if (mesh->mNumVertices > AI_MAX_ALLOC(aiVector3D)) {
                     throw DeadlyImportError("AC3D: Too many vertices, would run out of memory");
                     throw DeadlyImportError("AC3D: Too many vertices, would run out of memory");
                 }
                 }
                 aiVector3D* vertices = mesh->mVertices = new aiVector3D[mesh->mNumVertices];
                 aiVector3D* vertices = mesh->mVertices = new aiVector3D[mesh->mNumVertices];

+ 3 - 1
code/MD3Loader.cpp

@@ -785,7 +785,9 @@ void MD3Importer::InternReadFile( const std::string& pFile,
     pScene->mNumMeshes = pcHeader->NUM_SURFACES;
     pScene->mNumMeshes = pcHeader->NUM_SURFACES;
     if (pcHeader->NUM_SURFACES == 0) {
     if (pcHeader->NUM_SURFACES == 0) {
         throw DeadlyImportError("MD3: No surfaces");
         throw DeadlyImportError("MD3: No surfaces");
-    } else if (pcHeader->NUM_SURFACES > std::numeric_limits<int32_t>::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");
         throw DeadlyImportError("MD3: Too many surfaces, would run out of memory");
     }
     }
     pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
     pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];

+ 1 - 1
code/ObjFileImporter.cpp

@@ -382,7 +382,7 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
     pMesh->mNumVertices = numIndices;
     pMesh->mNumVertices = numIndices;
     if (pMesh->mNumVertices == 0) {
     if (pMesh->mNumVertices == 0) {
         throw DeadlyImportError( "OBJ: no vertices" );
         throw DeadlyImportError( "OBJ: no vertices" );
-    } else if (pMesh->mNumVertices > std::numeric_limits<int32_t>::max() / sizeof(aiVector3D)) {
+    } else if (pMesh->mNumVertices > AI_MAX_ALLOC(aiVector3D)) {
         throw DeadlyImportError( "OBJ: Too many vertices, would run out of memory" );
         throw DeadlyImportError( "OBJ: Too many vertices, would run out of memory" );
     }
     }
     pMesh->mVertices = new aiVector3D[ pMesh->mNumVertices ];
     pMesh->mVertices = new aiVector3D[ pMesh->mNumVertices ];

+ 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
 #   define AI_BUILD_BIG_ENDIAN
 #endif
 #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
 #endif // !! INCLUDED_AI_DEFINES_H