From 07c6df61f8456a6b02e88b369dcef5643ac1574e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20M=C3=A1cha?= Date: Thu, 9 May 2024 08:38:42 +0200 Subject: [PATCH 1/3] Assembly: removal of object of fixed joint causing crash FreeCAD is crashing if the 'Object' property of fixed joint (Assembly/Joints/Fixed/Joint Connector 1/Object1 or Assembly/Joints/Fixed/Joint Connector 2/Object2) is manually removed. Steps to reproduce: - make simple Assembly e.g. of two cubes with Fixed joint - Select Fixed joint in the tree and go-to property 'Data' tab - Select 'Object1' or 'Object2' of the 'Joint Connector 1' or 'Joint Connector 2' and remove this reference - click by your pointing device (mouse) to the arbitrary other property The FreeCAD will crash here because the call App::DocumentObject* obj = getObjFromNameProp(joint, propObjName, propPartName); will return NULL pointer. This problem is similar to the 4b5d079e6bf300fc629e9cd0d68d8d192d953d25. --- src/Mod/Assembly/App/AssemblyObject.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Mod/Assembly/App/AssemblyObject.cpp b/src/Mod/Assembly/App/AssemblyObject.cpp index 62b9e979a0c7..a1a19f54352d 100644 --- a/src/Mod/Assembly/App/AssemblyObject.cpp +++ b/src/Mod/Assembly/App/AssemblyObject.cpp @@ -1166,9 +1166,9 @@ std::string AssemblyObject::handleOneSideOfJoint(App::DocumentObject* joint, App::DocumentObject* part = getLinkObjFromProp(joint, propPartName); App::DocumentObject* obj = getObjFromNameProp(joint, propObjName, propPartName); - if (!part) { + if (!part || !obj) { Base::Console().Warning("The property %s or Joint %s is empty.", - propPartName, + obj ? propPartName : propObjName, joint->getFullName()); return ""; } From 968b06a6f663122b2fccc23896d6632fd823d3a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20M=C3=A1cha?= Date: Thu, 9 May 2024 09:07:35 +0200 Subject: [PATCH 2/3] Assembly: fixed warning message text The warning message text is not describing two cases which can happen, but only one - property of specific joint. --- src/Mod/Assembly/App/AssemblyObject.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Mod/Assembly/App/AssemblyObject.cpp b/src/Mod/Assembly/App/AssemblyObject.cpp index a1a19f54352d..37da308e60d5 100644 --- a/src/Mod/Assembly/App/AssemblyObject.cpp +++ b/src/Mod/Assembly/App/AssemblyObject.cpp @@ -1167,7 +1167,7 @@ std::string AssemblyObject::handleOneSideOfJoint(App::DocumentObject* joint, App::DocumentObject* obj = getObjFromNameProp(joint, propObjName, propPartName); if (!part || !obj) { - Base::Console().Warning("The property %s or Joint %s is empty.", + Base::Console().Warning("The property %s of Joint %s is empty.", obj ? propPartName : propObjName, joint->getFullName()); return ""; From f765a095af6161f7dd83f12c7f9f73add0174d86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20M=C3=A1cha?= Date: Mon, 20 May 2024 17:19:59 +0200 Subject: [PATCH 3/3] Assembly: avoiding possible crash in rack pinion joint code Similar problems: 07c6df61f8456a6b02e88b369dcef5643ac1574e and 4b5d079e6bf300fc629e9cd0d68d8d192d953d25 were causing real crashes (Linux + Sway Wayland compositor) when Fixed joint type was used. This patch tries to avoid the same situation, but now for the rack pinion joint type. The returned pointer value (part1 and obj1) can get NULL pointer value and is used in the code: if (obj1->getNameInDocument() != part1->getNameInDocument()) { .... a few lines later. --- src/Mod/Assembly/App/AssemblyObject.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Mod/Assembly/App/AssemblyObject.cpp b/src/Mod/Assembly/App/AssemblyObject.cpp index 37da308e60d5..6c656e4e8a46 100644 --- a/src/Mod/Assembly/App/AssemblyObject.cpp +++ b/src/Mod/Assembly/App/AssemblyObject.cpp @@ -1223,6 +1223,13 @@ void AssemblyObject::getRackPinionMarkers(App::DocumentObject* joint, App::DocumentObject* obj2 = getObjFromNameProp(joint, "Object2", "Part2"); Base::Placement plc2 = getPlacementFromProp(joint, "Placement2"); + if (!part1 || !obj1) { + Base::Console().Warning("The property %s of Joint %s is empty.", + obj1 ? "Part1" : "Object1", + joint->getFullName()); + return; + } + // For the pinion nothing special needed : markerNameJ = handleOneSideOfJoint(joint, "Object2", "Part2", "Placement2");