Преглед изворни кода

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 пре 8 година
родитељ
комит
7353d25c13
5 измењених фајлова са 24 додато и 0 уклоњено
  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) {