From 41de357e8fdcb68c2f0832d30b1dea951c269b28 Mon Sep 17 00:00:00 2001 From: wmayer Date: Wed, 20 Mar 2024 11:44:19 +0100 Subject: [PATCH] Issue #11989: Segfault on "Move Object to Other Body" The reason of the crash is a static_cast of an unknown type that causes undefined behaviour. The feature AdditiveLoft has the property Section of type PropertyLinkSubList but the function does a static_cast to PropertyLinkList. The solution is to use a dynamic_cast that returns null if the cast fails. --- src/Mod/PartDesign/Gui/Utils.cpp | 76 +++++++++++++++++++------------- 1 file changed, 46 insertions(+), 30 deletions(-) diff --git a/src/Mod/PartDesign/Gui/Utils.cpp b/src/Mod/PartDesign/Gui/Utils.cpp index 9620fec568..4da0af4ae6 100644 --- a/src/Mod/PartDesign/Gui/Utils.cpp +++ b/src/Mod/PartDesign/Gui/Utils.cpp @@ -454,46 +454,59 @@ void relinkToBody (PartDesign::Feature *feature) { bool isFeatureMovable(App::DocumentObject* const feat) { - if (!feat) + if (!feat) { return false; - - if (feat->isDerivedFrom()) { - auto prim = static_cast(feat); - App::DocumentObject* bf = prim->BaseFeature.getValue(); - if (bf) - return false; } - if (feat->isDerivedFrom()) { - auto prim = static_cast(feat); + if (auto prim = dynamic_cast(feat)) { + App::DocumentObject* bf = prim->BaseFeature.getValue(); + if (bf) { + return false; + } + } + + if (auto prim = dynamic_cast(feat)) { auto sk = prim->getVerifiedSketch(true); - if (!isFeatureMovable(sk)) + if (!isFeatureMovable(sk)) { return false; + } - if (auto prop = static_cast(prim->getPropertyByName("Sections"))) { - if (std::any_of(prop->getValues().begin(), prop->getValues().end(), [](App::DocumentObject* obj){ + if (auto prop = dynamic_cast(prim->getPropertyByName("Sections"))) { + if (std::any_of(prop->getValues().begin(), prop->getValues().end(), [](App::DocumentObject* obj) { return !isFeatureMovable(obj); - })) + })) { return false; + } } - if (auto prop = static_cast(prim->getPropertyByName("ReferenceAxis"))) { + if (auto prop = dynamic_cast(prim->getPropertyByName("Sections"))) { + if (std::any_of(prop->getValues().begin(), prop->getValues().end(), [](App::DocumentObject* obj) { + return !isFeatureMovable(obj); + })) { + return false; + } + } + + if (auto prop = dynamic_cast(prim->getPropertyByName("ReferenceAxis"))) { App::DocumentObject* axis = prop->getValue(); - if (axis && !isFeatureMovable(axis)) + if (axis && !isFeatureMovable(axis)) { return false; + } } - if (auto prop = static_cast(prim->getPropertyByName("Spine"))) { + if (auto prop = dynamic_cast(prim->getPropertyByName("Spine"))) { App::DocumentObject* spine = prop->getValue(); - if (spine && !isFeatureMovable(spine)) + if (spine && !isFeatureMovable(spine)) { return false; + } } - if (auto prop = static_cast(prim->getPropertyByName("AuxillerySpine"))) { + if (auto prop = dynamic_cast(prim->getPropertyByName("AuxillerySpine"))) { App::DocumentObject* auxSpine = prop->getValue(); - if (auxSpine && !isFeatureMovable(auxSpine)) + if (auxSpine && !isFeatureMovable(auxSpine)) { return false; + } } } @@ -501,8 +514,9 @@ bool isFeatureMovable(App::DocumentObject* const feat) if (feat->hasExtension(Part::AttachExtension::getExtensionClassTypeId())) { auto attachable = feat->getExtensionByType(); App::DocumentObject* support = attachable->AttachmentSupport.getValue(); - if (support && !support->isDerivedFrom()) + if (support && !support->isDerivedFrom()) { return false; + } } return true; @@ -512,34 +526,36 @@ std::vector collectMovableDependencies(std::vector unique_objs; - for (auto const &feat : features) - { - + for (auto const &feat : features) { // Get sketches and datums from profile based features - if (feat->isDerivedFrom()) { - auto prim = static_cast(feat); + if (auto prim = dynamic_cast(feat)) { Part::Part2DObject* sk = prim->getVerifiedSketch(true); if (sk) { - unique_objs.insert(static_cast(sk)); + unique_objs.insert(sk); } - if (auto prop = static_cast(prim->getPropertyByName("Sections"))) { + if (auto prop = dynamic_cast(prim->getPropertyByName("Sections"))) { for (App::DocumentObject* obj : prop->getValues()) { unique_objs.insert(obj); } } - if (auto prop = static_cast(prim->getPropertyByName("ReferenceAxis"))) { + if (auto prop = dynamic_cast(prim->getPropertyByName("Sections"))) { + for (App::DocumentObject* obj : prop->getValues()) { + unique_objs.insert(obj); + } + } + if (auto prop = dynamic_cast(prim->getPropertyByName("ReferenceAxis"))) { App::DocumentObject* axis = prop->getValue(); if (axis && !axis->isDerivedFrom()){ unique_objs.insert(axis); } } - if (auto prop = static_cast(prim->getPropertyByName("Spine"))) { + if (auto prop = dynamic_cast(prim->getPropertyByName("Spine"))) { App::DocumentObject* axis = prop->getValue(); if (axis && !axis->isDerivedFrom()){ unique_objs.insert(axis); } } - if (auto prop = static_cast(prim->getPropertyByName("AuxillerySpine"))) { + if (auto prop = dynamic_cast(prim->getPropertyByName("AuxillerySpine"))) { App::DocumentObject* axis = prop->getValue(); if (axis && !axis->isDerivedFrom()){ unique_objs.insert(axis);