Skip to content

Commit 41de357

Browse files
committed
Issue FreeCAD#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.
1 parent 0ae1ec4 commit 41de357

File tree

1 file changed

+43
-27
lines changed

1 file changed

+43
-27
lines changed

src/Mod/PartDesign/Gui/Utils.cpp

+43-27
Original file line numberDiff line numberDiff line change
@@ -454,55 +454,69 @@ void relinkToBody (PartDesign::Feature *feature) {
454454

455455
bool isFeatureMovable(App::DocumentObject* const feat)
456456
{
457-
if (!feat)
457+
if (!feat) {
458458
return false;
459+
}
459460

460-
if (feat->isDerivedFrom<PartDesign::Feature>()) {
461-
auto prim = static_cast<PartDesign::Feature*>(feat);
461+
if (auto prim = dynamic_cast<PartDesign::Feature*>(feat)) {
462462
App::DocumentObject* bf = prim->BaseFeature.getValue();
463-
if (bf)
463+
if (bf) {
464464
return false;
465+
}
465466
}
466467

467-
if (feat->isDerivedFrom<PartDesign::ProfileBased>()) {
468-
auto prim = static_cast<PartDesign::ProfileBased*>(feat);
468+
if (auto prim = dynamic_cast<PartDesign::ProfileBased*>(feat)) {
469469
auto sk = prim->getVerifiedSketch(true);
470470

471-
if (!isFeatureMovable(sk))
471+
if (!isFeatureMovable(sk)) {
472472
return false;
473+
}
473474

474-
if (auto prop = static_cast<App::PropertyLinkList*>(prim->getPropertyByName("Sections"))) {
475-
if (std::any_of(prop->getValues().begin(), prop->getValues().end(), [](App::DocumentObject* obj){
475+
if (auto prop = dynamic_cast<App::PropertyLinkList*>(prim->getPropertyByName("Sections"))) {
476+
if (std::any_of(prop->getValues().begin(), prop->getValues().end(), [](App::DocumentObject* obj) {
476477
return !isFeatureMovable(obj);
477-
}))
478+
})) {
478479
return false;
480+
}
479481
}
480482

481-
if (auto prop = static_cast<App::PropertyLinkSub*>(prim->getPropertyByName("ReferenceAxis"))) {
483+
if (auto prop = dynamic_cast<App::PropertyLinkSubList*>(prim->getPropertyByName("Sections"))) {
484+
if (std::any_of(prop->getValues().begin(), prop->getValues().end(), [](App::DocumentObject* obj) {
485+
return !isFeatureMovable(obj);
486+
})) {
487+
return false;
488+
}
489+
}
490+
491+
if (auto prop = dynamic_cast<App::PropertyLinkSub*>(prim->getPropertyByName("ReferenceAxis"))) {
482492
App::DocumentObject* axis = prop->getValue();
483-
if (axis && !isFeatureMovable(axis))
493+
if (axis && !isFeatureMovable(axis)) {
484494
return false;
495+
}
485496
}
486497

487-
if (auto prop = static_cast<App::PropertyLinkSub*>(prim->getPropertyByName("Spine"))) {
498+
if (auto prop = dynamic_cast<App::PropertyLinkSub*>(prim->getPropertyByName("Spine"))) {
488499
App::DocumentObject* spine = prop->getValue();
489-
if (spine && !isFeatureMovable(spine))
500+
if (spine && !isFeatureMovable(spine)) {
490501
return false;
502+
}
491503
}
492504

493-
if (auto prop = static_cast<App::PropertyLinkSub*>(prim->getPropertyByName("AuxillerySpine"))) {
505+
if (auto prop = dynamic_cast<App::PropertyLinkSub*>(prim->getPropertyByName("AuxillerySpine"))) {
494506
App::DocumentObject* auxSpine = prop->getValue();
495-
if (auxSpine && !isFeatureMovable(auxSpine))
507+
if (auxSpine && !isFeatureMovable(auxSpine)) {
496508
return false;
509+
}
497510
}
498511

499512
}
500513

501514
if (feat->hasExtension(Part::AttachExtension::getExtensionClassTypeId())) {
502515
auto attachable = feat->getExtensionByType<Part::AttachExtension>();
503516
App::DocumentObject* support = attachable->AttachmentSupport.getValue();
504-
if (support && !support->isDerivedFrom<App::OriginFeature>())
517+
if (support && !support->isDerivedFrom<App::OriginFeature>()) {
505518
return false;
519+
}
506520
}
507521

508522
return true;
@@ -512,34 +526,36 @@ std::vector<App::DocumentObject*> collectMovableDependencies(std::vector<App::Do
512526
{
513527
std::set<App::DocumentObject*> unique_objs;
514528

515-
for (auto const &feat : features)
516-
{
517-
529+
for (auto const &feat : features) {
518530
// Get sketches and datums from profile based features
519-
if (feat->isDerivedFrom<PartDesign::ProfileBased>()) {
520-
auto prim = static_cast<PartDesign::ProfileBased*>(feat);
531+
if (auto prim = dynamic_cast<PartDesign::ProfileBased*>(feat)) {
521532
Part::Part2DObject* sk = prim->getVerifiedSketch(true);
522533
if (sk) {
523-
unique_objs.insert(static_cast<App::DocumentObject*>(sk));
534+
unique_objs.insert(sk);
535+
}
536+
if (auto prop = dynamic_cast<App::PropertyLinkList*>(prim->getPropertyByName("Sections"))) {
537+
for (App::DocumentObject* obj : prop->getValues()) {
538+
unique_objs.insert(obj);
539+
}
524540
}
525-
if (auto prop = static_cast<App::PropertyLinkList*>(prim->getPropertyByName("Sections"))) {
541+
if (auto prop = dynamic_cast<App::PropertyLinkSubList*>(prim->getPropertyByName("Sections"))) {
526542
for (App::DocumentObject* obj : prop->getValues()) {
527543
unique_objs.insert(obj);
528544
}
529545
}
530-
if (auto prop = static_cast<App::PropertyLinkSub*>(prim->getPropertyByName("ReferenceAxis"))) {
546+
if (auto prop = dynamic_cast<App::PropertyLinkSub*>(prim->getPropertyByName("ReferenceAxis"))) {
531547
App::DocumentObject* axis = prop->getValue();
532548
if (axis && !axis->isDerivedFrom<App::OriginFeature>()){
533549
unique_objs.insert(axis);
534550
}
535551
}
536-
if (auto prop = static_cast<App::PropertyLinkSub*>(prim->getPropertyByName("Spine"))) {
552+
if (auto prop = dynamic_cast<App::PropertyLinkSub*>(prim->getPropertyByName("Spine"))) {
537553
App::DocumentObject* axis = prop->getValue();
538554
if (axis && !axis->isDerivedFrom<App::OriginFeature>()){
539555
unique_objs.insert(axis);
540556
}
541557
}
542-
if (auto prop = static_cast<App::PropertyLinkSub*>(prim->getPropertyByName("AuxillerySpine"))) {
558+
if (auto prop = dynamic_cast<App::PropertyLinkSub*>(prim->getPropertyByName("AuxillerySpine"))) {
543559
App::DocumentObject* axis = prop->getValue();
544560
if (axis && !axis->isDerivedFrom<App::OriginFeature>()){
545561
unique_objs.insert(axis);

0 commit comments

Comments
 (0)