From 79b6529991f75c2d58fd2d75ffc19613364ba007 Mon Sep 17 00:00:00 2001 From: Pasukhin Dmitry Date: Sun, 14 Jun 2026 10:45:03 +0100 Subject: [PATCH] Modeling Algorithms - Guard null curve in BRepExtrema_DistanceSS (#1307) BRep_Tool::Curve() may return a null handle for edges without a 3D curve (e.g. edges defined only by pcurves on a surface). The two call sites in BRepExtrema_DistanceSS dereferenced the returned handle without a null check, causing a crash when such edges were encountered in edge-edge (PERFORM_C0) or edge-face distance computations. Add null checks before dereferencing pCurv and return early if the handle is null. Add GTests covering both code paths. --- .../BRepExtrema/BRepExtrema_DistanceSS.cxx | 11 ++++ .../BRepExtrema_DistShapeShape_Test.cxx | 51 +++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/src/ModelingAlgorithms/TKTopAlgo/BRepExtrema/BRepExtrema_DistanceSS.cxx b/src/ModelingAlgorithms/TKTopAlgo/BRepExtrema/BRepExtrema_DistanceSS.cxx index a285be0673..f6cedf30a4 100644 --- a/src/ModelingAlgorithms/TKTopAlgo/BRepExtrema/BRepExtrema_DistanceSS.cxx +++ b/src/ModelingAlgorithms/TKTopAlgo/BRepExtrema/BRepExtrema_DistanceSS.cxx @@ -517,6 +517,11 @@ static void PERFORM_C0(const TopoDS_Edge& S1, double aFOther, aLOther; occ::handle pCurvOther = BRep_Tool::Curve(Eother, aFOther, aLOther); + if (pCurv.IsNull()) + { + return; + } + if (pCurv->Continuity() == GeomAbs_C0) { constexpr double epsP = Precision::PConfusion(); @@ -1096,6 +1101,12 @@ void BRepExtrema_DistanceSS::Perform( double aFirst, aLast; occ::handle pCurv = BRep_Tool::Curve(theS1, aFirst, aLast); + + if (pCurv.IsNull()) + { + return; + } + if (pCurv->Continuity() == GeomAbs_C0) { NCollection_Sequence SeqSolution1; diff --git a/src/ModelingAlgorithms/TKTopAlgo/GTests/BRepExtrema_DistShapeShape_Test.cxx b/src/ModelingAlgorithms/TKTopAlgo/GTests/BRepExtrema_DistShapeShape_Test.cxx index 297c8715bb..6f8d1ec28c 100644 --- a/src/ModelingAlgorithms/TKTopAlgo/GTests/BRepExtrema_DistShapeShape_Test.cxx +++ b/src/ModelingAlgorithms/TKTopAlgo/GTests/BRepExtrema_DistShapeShape_Test.cxx @@ -13,11 +13,21 @@ #include +#include #include +#include #include #include +#include +#include +#include +#include +#include +#include +#include #include #include +#include #include //================================================================================================= @@ -41,3 +51,44 @@ TEST(BRepExtrema_DistShapeShapeTest, BUC60870_EdgeToVertexMinimumDistance) EXPECT_NEAR(aDist.Value(), aTheorDist, aTheorDist * aPercentMax) << "Minimum distance deviates from expected value 1.0"; } + +//================================================================================================= + +// Verify that BRepExtrema_DistShapeShape does not crash when computing the distance +// between two edges and one of them has no 3D curve (null Geom_Curve from BRep_Tool::Curve). +// This exercises the null-check in the PERFORM_C0 helper. +TEST(BRepExtrema_DistShapeShapeTest, EdgeEdge_Null3DCurve_NoCrash) +{ + const TopoDS_Edge aEdge1 = BRepBuilderAPI_MakeEdge(gp_Pnt(0, 0, 0), gp_Pnt(1, 0, 0)).Edge(); + + const occ::handle aCircle = + new Geom_Circle(gp_Ax2(gp_Pnt(5, 0, 0), gp_Dir(0, 0, 1)), 1.0); + TopoDS_Edge aEdge2 = BRepBuilderAPI_MakeEdge(aCircle).Edge(); + + BRep_Builder aBuilder; + aBuilder.UpdateEdge(aEdge2, occ::handle(), 1e-7); + + BRepExtrema_DistShapeShape aDist(aEdge1, aEdge2, 10.0); + (void)aDist; +} + +//================================================================================================= + +// Verify that BRepExtrema_DistShapeShape does not crash when computing the distance +// between an edge with no 3D curve and a face. +// This exercises the null-check in Perform(Edge, Face). +TEST(BRepExtrema_DistShapeShapeTest, EdgeFace_Null3DCurve_NoCrash) +{ + const occ::handle aCircle = + new Geom_Circle(gp_Ax2(gp_Pnt(5, 0, 0), gp_Dir(0, 0, 1)), 1.0); + TopoDS_Edge aEdge = BRepBuilderAPI_MakeEdge(aCircle).Edge(); + + BRep_Builder aBuilder; + aBuilder.UpdateEdge(aEdge, occ::handle(), 1e-7); + + const TopoDS_Face aFace = + BRepBuilderAPI_MakeFace(gp_Pln(gp_Pnt(0, 0, 5), gp_Dir(0, 0, 1)), -10, 10, -10, 10); + + BRepExtrema_DistShapeShape aDist(aEdge, aFace, 10.0); + (void)aDist; +}