From 7353d25c139e97f19ce0de433f883a0bd7807d76 Mon Sep 17 00:00:00 2001 From: Haik Lorenz Date: Mon, 9 Oct 2017 15:47:17 +0200 Subject: [PATCH 1/2] 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. --- code/ColladaExporter.cpp | 4 ++++ code/ObjExporter.cpp | 4 ++++ code/PlyExporter.cpp | 4 ++++ code/STLExporter.cpp | 8 ++++++++ code/XFileExporter.cpp | 4 ++++ 5 files changed, 24 insertions(+) diff --git a/code/ColladaExporter.cpp b/code/ColladaExporter.cpp index 1bac8b7f6..8f2e4047b 100644 --- a/code/ColladaExporter.cpp +++ b/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 outfile (pIOSystem->Open(pFile,"wt")); diff --git a/code/ObjExporter.cpp b/code/ObjExporter.cpp index d10dfcd45..ea3e19cd9 100644 --- a/code/ObjExporter.cpp +++ b/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 outfile (pIOSystem->Open(pFile,"wt")); diff --git a/code/PlyExporter.cpp b/code/PlyExporter.cpp index 1d14c9219..bd3c94830 100644 --- a/code/PlyExporter.cpp +++ b/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 outfile (pIOSystem->Open(pFile,"wt")); if(outfile == NULL) { diff --git a/code/STLExporter.cpp b/code/STLExporter.cpp index 3905cbcaf..c9d554655 100644 --- a/code/STLExporter.cpp +++ b/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 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 outfile (pIOSystem->Open(pFile,"wb")); if(outfile == NULL) { diff --git a/code/XFileExporter.cpp b/code/XFileExporter.cpp index 30a0a21f8..1e77c8b81 100644 --- a/code/XFileExporter.cpp +++ b/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 outfile (pIOSystem->Open(pFile,"wt")); if(outfile == NULL) { From b2eb599176dfa5e98285e992422515455ccf137a Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Mon, 16 Oct 2017 18:51:25 +0200 Subject: [PATCH 2/2] Update ColladaExporter.cpp Retrigger travis. --- code/ColladaExporter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/ColladaExporter.cpp b/code/ColladaExporter.cpp index 691ef9500..53ee07388 100644 --- a/code/ColladaExporter.cpp +++ b/code/ColladaExporter.cpp @@ -108,7 +108,7 @@ ColladaExporter::ColladaExporter( const aiScene* pScene, IOSystem* pIOSystem, co // set up strings endstr = "\n"; - // start writing + // start writing the file WriteFile(); }