Explorar o código

Prevent failing stringstream to crash the export process

Text exporters are using string streams to hold the file content first and then write them to the file in a single pass. If for whatever reason the stream has the fail bit set, tellp() will return pos_type(-1), which in turn makes the subsequent write crash - at least on Windows systems. One reason for the stream being in fail state is when its size exceeds 2^31 bytes, even on 64-bit systems (i.e., when very large scenes get exported).

The fix is checking the fail() before even opening the file.
Haik Lorenz %!s(int64=8) %!d(string=hai) anos
pai
achega
7353d25c13
Modificáronse 5 ficheiros con 24 adicións e 0 borrados
  1. 4 0
      code/ColladaExporter.cpp
  2. 4 0
      code/ObjExporter.cpp
  3. 4 0
      code/PlyExporter.cpp
  4. 8 0
      code/STLExporter.cpp
  5. 4 0
      code/XFileExporter.cpp

+ 4 - 0
code/ColladaExporter.cpp

@@ -72,6 +72,10 @@ void ExportSceneCollada(const char* pFile, IOSystem* pIOSystem, const aiScene* p
 
     // invoke the exporter
     ColladaExporter iDoTheExportThing( pScene, pIOSystem, path, file);
+    
+    if (iDoTheExportThing.mOutput.fail()) {
+        throw DeadlyExportError("output data creation failed. Most likely the file became too large: " + std::string(pFile));
+    }
 
     // we're still here - export successfully completed. Write result to the given IOSYstem
     std::unique_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt"));

+ 4 - 0
code/ObjExporter.cpp

@@ -61,6 +61,10 @@ void ExportSceneObj(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene
     // invoke the exporter
     ObjExporter exporter(pFile, pScene);
 
+    if (exporter.mOutput.fail() || exporter.mOutputMat.fail()) {
+        throw DeadlyExportError("output data creation failed. Most likely the file became too large: " + std::string(pFile));
+    }
+
     // we're still here - export successfully completed. Write both the main OBJ file and the material script
     {
         std::unique_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt"));

+ 4 - 0
code/PlyExporter.cpp

@@ -69,6 +69,10 @@ void ExportScenePly(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene
     // invoke the exporter
     PlyExporter exporter(pFile, pScene);
 
+    if (exporter.mOutput.fail()) {
+        throw DeadlyExportError("output data creation failed. Most likely the file became too large: " + std::string(pFile));
+    }
+
     // we're still here - export successfully completed. Write the file.
     std::unique_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt"));
     if(outfile == NULL) {

+ 8 - 0
code/STLExporter.cpp

@@ -61,6 +61,10 @@ void ExportSceneSTL(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene
     // invoke the exporter
     STLExporter exporter(pFile, pScene);
 
+    if (exporter.mOutput.fail()) {
+        throw DeadlyExportError("output data creation failed. Most likely the file became too large: " + std::string(pFile));
+    }
+    
     // we're still here - export successfully completed. Write the file.
     std::unique_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt"));
     if(outfile == NULL) {
@@ -74,6 +78,10 @@ void ExportSceneSTLBinary(const char* pFile,IOSystem* pIOSystem, const aiScene*
     // invoke the exporter
     STLExporter exporter(pFile, pScene, true);
 
+    if (exporter.mOutput.fail()) {
+        throw DeadlyExportError("output data creation failed. Most likely the file became too large: " + std::string(pFile));
+    }
+    
     // we're still here - export successfully completed. Write the file.
     std::unique_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wb"));
     if(outfile == NULL) {

+ 4 - 0
code/XFileExporter.cpp

@@ -78,6 +78,10 @@ void ExportSceneXFile(const char* pFile,IOSystem* pIOSystem, const aiScene* pSce
     // invoke the exporter
     XFileExporter iDoTheExportThing( pScene, pIOSystem, path, file, &props);
 
+    if (iDoTheExportThing.mOutput.fail()) {
+        throw DeadlyExportError("output data creation failed. Most likely the file became too large: " + std::string(pFile));
+    }
+    
     // we're still here - export successfully completed. Write result to the given IOSYstem
     std::unique_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt"));
     if(outfile == NULL) {