From bb1aec9e60faa8b279306bfebe672b8d4e77351d Mon Sep 17 00:00:00 2001 From: wmayer Date: Fri, 25 Oct 2019 20:58:06 +0200 Subject: [PATCH] fix crash when restoring a corrupted project fails --- src/App/Application.cpp | 85 ++++++++++++++++++++++++----------------- 1 file changed, 49 insertions(+), 36 deletions(-) diff --git a/src/App/Application.cpp b/src/App/Application.cpp index 9c9e629e6e..46b81602df 100644 --- a/src/App/Application.cpp +++ b/src/App/Application.cpp @@ -594,21 +594,20 @@ Document* Application::openDocument(const char * FileName, bool createView) { return 0; } -std::vector Application::openDocuments( - const std::vector &filenames, - const std::vector *paths, - const std::vector *labels, - std::vector *errs, - bool createView) +std::vector Application::openDocuments(const std::vector &filenames, + const std::vector *paths, + const std::vector *labels, + std::vector *errs, + bool createView) { - std::vector res(filenames.size(),nullptr); - if(filenames.empty()) + std::vector res(filenames.size(), nullptr); + if (filenames.empty()) return res; - if(errs) + if (errs) errs->resize(filenames.size()); - DocOpenGuard guard(_isRestoring,signalFinishOpenDocument); + DocOpenGuard guard(_isRestoring, signalFinishOpenDocument); _pendingDocs.clear(); _pendingDocsReopen.clear(); _pendingDocMap.clear(); @@ -618,88 +617,102 @@ std::vector Application::openDocuments( ParameterGrp::handle hGrp = GetParameterGroupByPath("User parameter:BaseApp/Preferences/Document"); _allowPartial = !hGrp->GetBool("NoPartialLoading",false); - for(auto &name : filenames) + for (auto &name : filenames) _pendingDocs.push_back(name.c_str()); std::deque > newDocs; FC_TIME_INIT(t); - for(std::size_t count=0;;++count) { + for (std::size_t count=0;; ++count) { const char *name = _pendingDocs.front(); _pendingDocs.pop_front(); - bool isMainDoc = count objNames; - if(_allowPartial) { + if (_allowPartial) { auto it = _pendingDocMap.find(name); - if(it!=_pendingDocMap.end()) + if (it != _pendingDocMap.end()) objNames.swap(it->second); } + FC_TIME_INIT(t1); DocTiming timing; + const char *path = name; const char *label = 0; - if(isMainDoc) { - if(paths && paths->size()>count) + if (isMainDoc) { + if (paths && paths->size()>count) path = (*paths)[count].c_str(); - if(labels && labels->size()>count) + + if (labels && labels->size()>count) label = (*labels)[count].c_str(); } - auto doc = openDocumentPrivate(path,name,label,isMainDoc,createView,objNames); + + auto doc = openDocumentPrivate(path, name, label, isMainDoc, createView, objNames); FC_DURATION_PLUS(timing.d1,t1); - if(doc) + if (doc) newDocs.emplace_front(doc,timing); - if(isMainDoc) + + if (isMainDoc) res[count] = doc; _objCount = -1; - }catch(const Base::Exception &e) { - if(!errs && isMainDoc) + } + catch (const Base::Exception &e) { + if (!errs && isMainDoc) throw; - if(errs && isMainDoc) + if (errs && isMainDoc) (*errs)[count] = e.what(); else Console().Error("Exception opening file: %s [%s]\n", name, e.what()); - }catch(const std::exception &e) { - if(!errs && isMainDoc) + } + catch (const std::exception &e) { + if (!errs && isMainDoc) throw; - if(errs && isMainDoc) + if (errs && isMainDoc) (*errs)[count] = e.what(); else Console().Error("Exception opening file: %s [%s]\n", name, e.what()); - }catch(...) { - if(errs) { - if(isMainDoc) + } + catch (...) { + if (errs) { + if (isMainDoc) (*errs)[count] = "unknown error"; - } else { + } + else { _pendingDocs.clear(); _pendingDocsReopen.clear(); _pendingDocMap.clear(); throw; } } - if(_pendingDocs.empty()) { - if(_pendingDocsReopen.empty()) + + if (_pendingDocs.empty()) { + if (_pendingDocsReopen.empty()) break; _allowPartial = false; _pendingDocs.swap(_pendingDocsReopen); } } + _pendingDocs.clear(); _pendingDocsReopen.clear(); _pendingDocMap.clear(); Base::SequencerLauncher seq("Postprocessing...", newDocs.size()); - for(auto &v : newDocs) { + for (auto &v : newDocs) { FC_TIME_INIT(t1); v.first->afterRestore(true); FC_DURATION_PLUS(v.second.d2,t1); seq.next(); } - setActiveDocument(newDocs.back().first); - for(auto &v : newDocs) { + if (!newDocs.empty()) + setActiveDocument(newDocs.back().first); + + for (auto &v : newDocs) { FC_DURATION_LOG(v.second.d1, v.first->getName() << " restore"); FC_DURATION_LOG(v.second.d2, v.first->getName() << " postprocess"); }