From a16e4191380cea054e03c81732af9d0c4be269ec Mon Sep 17 00:00:00 2001 From: tamasmeszaros <meszaros.q@gmail.com> Date: Thu, 13 Dec 2018 18:49:08 +0100 Subject: [PATCH] Fix for SPE-688 (crash when saving zip to low disk space) --- src/libslic3r/PrintExport.hpp | 14 ++++++++++---- src/slic3r/GUI/BackgroundSlicingProcess.cpp | 13 ++++++++++++- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/libslic3r/PrintExport.hpp b/src/libslic3r/PrintExport.hpp index 8187d7bf0..5cfb55217 100644 --- a/src/libslic3r/PrintExport.hpp +++ b/src/libslic3r/PrintExport.hpp @@ -227,29 +227,35 @@ public: inline void save(const std::string& path) { try { LayerWriter<LyrFmt> writer(path); + if(!writer.is_ok()) return; std::string project = writer.get_name(); writer.next_entry("config.ini"); + if(!writer.is_ok()) return; + writer << createIniContent(project); - for(unsigned i = 0; i < m_layers_rst.size(); i++) { + for(unsigned i = 0; i < m_layers_rst.size() && writer.is_ok(); i++) + { if(m_layers_rst[i].second.rdbuf()->in_avail() > 0) { char lyrnum[6]; std::sprintf(lyrnum, "%.5d", i); auto zfilename = project + lyrnum + ".png"; writer.next_entry(zfilename); + + if(!writer.is_ok()) break; + writer << m_layers_rst[i].second.str(); // writer << m_layers_rst[i].second.rdbuf(); // we can keep the date for later calls of this method //m_layers_rst[i].second.str(""); } } - - writer.close(); } catch(std::exception& e) { BOOST_LOG_TRIVIAL(error) << e.what(); - return; + // Rethrow the exception + throw; } } diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.cpp b/src/slic3r/GUI/BackgroundSlicingProcess.cpp index b9f146013..891e5f0dc 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.cpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.cpp @@ -113,10 +113,17 @@ public: zipstream(zipfile), pngstream(zipstream) { - if(!zipfile.IsOk()) + if(!is_ok()) throw std::runtime_error("Cannot create zip file."); } + ~LayerWriter() { + // In case of an error (disk space full) zipstream destructor would + // crash. + pngstream.clear(); + zipstream.CloseEntry(); + } + inline void next_entry(const std::string& fname) { zipstream.PutNextEntry(fname); } @@ -129,6 +136,10 @@ public: pngstream << arg; return *this; } + bool is_ok() const { + return pngstream.good() && zipstream.IsOk() && zipfile.IsOk(); + } + inline void close() { zipstream.Close(); zipfile.Close();