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.
This commit is contained in:
Pasukhin Dmitry
2026-06-14 10:45:03 +01:00
committed by GitHub
parent d15ffb983d
commit 79b6529991
2 changed files with 62 additions and 0 deletions
@@ -517,6 +517,11 @@ static void PERFORM_C0(const TopoDS_Edge& S1,
double aFOther, aLOther;
occ::handle<Geom_Curve> 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<Geom_Curve> pCurv = BRep_Tool::Curve(theS1, aFirst, aLast);
if (pCurv.IsNull())
{
return;
}
if (pCurv->Continuity() == GeomAbs_C0)
{
NCollection_Sequence<BRepExtrema_SolutionElem> SeqSolution1;
@@ -13,11 +13,21 @@
#include <gtest/gtest.h>
#include <BRep_Builder.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
#include <BRepBuilderAPI_MakeVertex.hxx>
#include <BRepExtrema_DistShapeShape.hxx>
#include <Geom_Circle.hxx>
#include <Geom_Line.hxx>
#include <gp_Ax2.hxx>
#include <gp_Circ.hxx>
#include <gp_Dir.hxx>
#include <gp_Lin.hxx>
#include <gp_Pln.hxx>
#include <gp_Pnt.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Vertex.hxx>
//=================================================================================================
@@ -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<Geom_Circle> 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<Geom_Curve>(), 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<Geom_Circle> 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<Geom_Curve>(), 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;
}