From c00699b15d5f09de4140c8dd02f661fb30d5bbb0 Mon Sep 17 00:00:00 2001 From: marioalexis Date: Sun, 22 May 2022 02:43:55 -0300 Subject: [PATCH] Gui: Prevent crash when trying to delete pointer to BaseClass --- src/Gui/Document.cpp | 15 ++++++++------- src/Gui/View3DInventorViewer.cpp | 14 ++++---------- src/Gui/WorkbenchManager.cpp | 26 ++++++++++---------------- 3 files changed, 22 insertions(+), 33 deletions(-) diff --git a/src/Gui/Document.cpp b/src/Gui/Document.cpp index 93658f5f6e..198e2041ef 100644 --- a/src/Gui/Document.cpp +++ b/src/Gui/Document.cpp @@ -667,21 +667,22 @@ void Document::slotNewObject(const App::DocumentObject& Obj) FC_LOG(Obj.getFullName() << " has no view provider specified"); return; } - Base::BaseClass* base = static_cast( - Base::Type::createInstanceByName(cName.c_str(),true)); - pcProvider = Base::freecad_dynamic_cast(base); + Base::Type type = Base::Type::getTypeIfDerivedFrom(cName.c_str(), ViewProviderDocumentObject::getClassTypeId(), true); + pcProvider = static_cast(type.createInstance()); + // createInstance could return a null pointer if (!pcProvider) { // type not derived from ViewProviderDocumentObject!!! FC_ERR("Invalid view provider type '" << cName << "' for " << Obj.getFullName()); - delete base; return; - } else if (cName!=Obj.getViewProviderName() && !pcProvider->allowOverride(Obj)) { + } + else if (cName!=Obj.getViewProviderName() && !pcProvider->allowOverride(Obj)) { FC_WARN("View provider type '" << cName << "' does not support " << Obj.getFullName()); - delete base; pcProvider = nullptr; cName = Obj.getViewProviderName(); - } else + } + else { break; + } } setModified(true); diff --git a/src/Gui/View3DInventorViewer.cpp b/src/Gui/View3DInventorViewer.cpp index f75ecd5639..110212896a 100644 --- a/src/Gui/View3DInventorViewer.cpp +++ b/src/Gui/View3DInventorViewer.cpp @@ -1445,18 +1445,13 @@ bool View3DInventorViewer::hasAxisCross(void) void View3DInventorViewer::setNavigationType(Base::Type t) { - if (t.isBad()) - return; - if (this->navigation && this->navigation->getTypeId() == t) return; // nothing to do - Base::BaseClass* base = static_cast(t.createInstance()); - if (!base) - return; - - if (!base->getTypeId().isDerivedFrom(NavigationStyle::getClassTypeId())) { - delete base; + Base::Type type = Base::Type::getTypeIfDerivedFrom(t.getName(), NavigationStyle::getClassTypeId()); + NavigationStyle* ns = static_cast(type.createInstance()); + // createInstance could return a null pointer + if (!ns) { #if FC_DEBUG SoDebugError::postWarning("View3DInventorViewer::setNavigationType", "Navigation object must be of type NavigationStyle."); @@ -1464,7 +1459,6 @@ void View3DInventorViewer::setNavigationType(Base::Type t) return; } - NavigationStyle* ns = static_cast(base); if (this->navigation) { ns->operator = (*this->navigation); delete this->navigation; diff --git a/src/Gui/WorkbenchManager.cpp b/src/Gui/WorkbenchManager.cpp index 8e5c977785..3da0131fa7 100644 --- a/src/Gui/WorkbenchManager.cpp +++ b/src/Gui/WorkbenchManager.cpp @@ -71,23 +71,17 @@ Workbench* WorkbenchManager::createWorkbench (const std::string& name, const std if (!wb) { // try to create an instance now - Base::BaseClass* base = static_cast - (Base::Type::createInstanceByName(className.c_str(),false)); - if (base) { - if (!base->getTypeId().isDerivedFrom(Gui::Workbench::getClassTypeId())) { - delete base; - std::stringstream str; - str << "'" << className << "' not a workbench type" << std::ends; - throw Base::TypeError(str.str()); - } - - wb = static_cast(base); - wb->setName(name); - _workbenches[name] = wb; + Base::Type type = Base::Type::getTypeIfDerivedFrom(className.c_str(), Workbench::getClassTypeId(), true); + wb = static_cast(type.createInstance()); + // createInstance could return a null pointer + if (!wb) { + std::stringstream str; + str << "'" << className << "' not a workbench type" << std::ends; + throw Base::TypeError(str.str()); } - else - Base::Console().Log("WorkbenchManager::createWorkbench(): Can not create " - "Workbench instance with type: %s\n",className.c_str()); + + wb->setName(name); + _workbenches[name] = wb; } return wb;