From 71f70eb8558d527a2a4ed9b0a4be053f1e558862 Mon Sep 17 00:00:00 2001 From: DeepSOIC Date: Sat, 14 May 2016 02:14:51 +0300 Subject: [PATCH] AttachEngine: fix crash when referenced objects get deleted ... by verifying if the pointers equal to objects contained in all open documents. Not terribly good, but I can't think of a situation where doing this search might cause trouble. --- src/Mod/Part/App/AttachEnginePyImp.cpp | 2 ++ src/Mod/Part/App/Attacher.cpp | 20 ++++++++++++++++++++ src/Mod/Part/App/Attacher.h | 6 ++++++ 3 files changed, 28 insertions(+) diff --git a/src/Mod/Part/App/AttachEnginePyImp.cpp b/src/Mod/Part/App/AttachEnginePyImp.cpp index 9984218c3..e497dcbcf 100644 --- a/src/Mod/Part/App/AttachEnginePyImp.cpp +++ b/src/Mod/Part/App/AttachEnginePyImp.cpp @@ -111,6 +111,7 @@ Py::Object AttachEnginePy::getReferences(void) const { try { AttachEngine &attacher = *(this->getAttachEnginePtr()); + AttachEngine::verifyReferencesAreSafe(attacher.references); return Py::Object(attacher.references.getPyObject(),true); } ATTACHERPY_STDCATCH_ATTR; } @@ -523,6 +524,7 @@ PyObject* AttachEnginePy::writeParametersToFeature(PyObject* args) } Part::AttachableObject* feat = static_cast(dobj); const AttachEngine &attacher = *(this->getAttachEnginePtr()); + AttachEngine::verifyReferencesAreSafe(attacher.references); feat->Support.Paste(attacher.references); feat->MapMode.setValue(attacher.mapMode); feat->MapReversed.setValue(attacher.mapReverse); diff --git a/src/Mod/Part/App/Attacher.cpp b/src/Mod/Part/App/Attacher.cpp index d0a83b0d8..9fbbc085d 100644 --- a/src/Mod/Part/App/Attacher.cpp +++ b/src/Mod/Part/App/Attacher.cpp @@ -61,6 +61,8 @@ #include "Attacher.h" #include #include +#include +#include using namespace Part; using namespace Attacher; @@ -749,6 +751,7 @@ void AttachEngine::readLinks(const App::PropertyLinkSubList &references, std::vector &storage, std::vector &types) { + verifyReferencesAreSafe(references); const std::vector &objs = references.getValues(); const std::vector &sub = references.getSubValues(); geofs.resize(objs.size()); @@ -830,6 +833,23 @@ void AttachEngine::throwWrongMode(eMapMode mmode) throw Base::Exception(errmsg.str().c_str()); } +void AttachEngine::verifyReferencesAreSafe(const App::PropertyLinkSubList &references) +{ + const std::vector links = references.getValues(); + const std::vector docs = App::GetApplication().getDocuments(); + for(App::DocumentObject* lnk : links){ + bool found = false; + for(App::Document* doc : docs){ + if(doc->isIn(lnk)){ + found = true; + } + } + if (!found){ + throw Base::Exception("AttachEngine: verifyReferencesAreSafe: references point to deleted object."); + } + } +} + //================================================================================= diff --git a/src/Mod/Part/App/Attacher.h b/src/Mod/Part/App/Attacher.h index c0e880401..b2d22b637 100644 --- a/src/Mod/Part/App/Attacher.h +++ b/src/Mod/Part/App/Attacher.h @@ -342,6 +342,12 @@ public://helper functions that may be useful outside of the class static GProp_GProps getInertialPropsOfShape(const std::vector &shapes); + /** + * @brief verifyReferencesAreSafe: checks if pointers in references still + * point to objects contained in open documents. This guarantees the links + * are valid. Throws Base::Exception if invalid links are found. + */ + static void verifyReferencesAreSafe(const App::PropertyLinkSubList& references); public: //enums static const char* eMapModeStrings[];