Skip to content

Modeling Algorithms - Fix ChFi2d_Builder::AddChamfer null-edge dereference on a repeated pair - #1432

Open
gsdali wants to merge 1 commit into
Open-Cascade-SAS:masterfrom
gsdali:fix/705-chfi2d-addchamfer-repeated-pair
Open

Modeling Algorithms - Fix ChFi2d_Builder::AddChamfer null-edge dereference on a repeated pair#1432
gsdali wants to merge 1 commit into
Open-Cascade-SAS:masterfrom
gsdali:fix/705-chfi2d-addchamfer-repeated-pair

Conversation

@gsdali

@gsdali gsdali commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Description of the change

ChFi2d_Builder::AddChamfer(const TopoDS_Edge& E1, const TopoDS_Edge& E2, double D1, double D2)
calls ChFi2d::FindConnectedEdges and dereferences the two edges it returns without checking the
returned status first. FindConnectedEdges leaves both edges null on every failure path, and a
second call naming the same edge pair hits exactly that: the pair's shared vertex is removed from
the face's wire by the first call's own BuildNewWire, so the second call's lookup fails and the
two null edges it returns reach ComputeChamfer unchecked.

Adds the same status check the sibling overload, AddChamfer(const TopoDS_Edge& E, const TopoDS_Vertex& V, double D, double Ang), already has immediately after the identical
FindConnectedEdges call:

status = ChFi2d::FindConnectedEdges(newFace, commonVertex, EE1, EE2);
if (status == ChFi2d_ConnexionError)
{
  return chamfer;
}

chamfer is the default-constructed null edge this function already returns on its other refusal
paths (ChFi2d_Builder_0.cxx lines 83, 89, 95), so this reuses the existing "declined" signal
rather than introducing a new one.

Related issue

Fixes #1431.

Type of change

  • Bug fix (non-breaking change which fixes an issue)

How Has This Been Tested?

  1. Standalone repro (attached in ChFi2d_Builder::AddChamfer(edge, edge, ...) SIGSEGVs on a repeated edge pair (unchecked FindConnectedEdges status) #1431): a rectangular planar face, BRepFilletAPI_MakeFillet2d::AddChamfer
    called twice with the identical edge pair. On stock master, the second call SIGSEGVs 100% of
    the time (ComputeChamfer, both edges null).
  2. Debug (-O0) single-TU override-link (this file compiled standalone and linked before the OCCT
    static archive, so the linker resolves this TU's symbols from the override): before the patch,
    the second call crashes; after, it returns a null edge with Status() == ChFi2d_ConnexionError,
    matching the sibling overload's own answer for an unconnected vertex.
  3. The first call in both cases is unaffected: Status() == ChFi2d_IsDone, non-null edge, same
    geometry before and after.
  4. clang-format --dry-run --Werror on the touched file reports only pre-existing violations
    elsewhere in the file (Geom2dInt_GInter construction, unrelated lines), unchanged in count and
    content before and after this patch; the four added lines are clean.

Checklist:

  • My code follows the code style of this project
  • I have commented my code, particularly in hard-to-understand areas — N/A, the added check
    mirrors the sibling overload's own existing, uncommented idiom line for line
  • My change requires a change to the documentation — N/A, no public API/behavior change beyond
    "does not crash"
  • I have added tests to cover my changes — regression coverage lives in the downstream Swift
    wrapper project (OCCTSwift), which found this crash through a fillet/chamfer contract audit;
    happy to add a DRAW test if maintainers point me at the right harness/fixture convention for
    this area

@dpasukhi

dpasukhi commented Aug 10, 2026

Copy link
Copy Markdown
Member

Dear @gsdali please add GTest to cover your changes, you can follow the logic of all exited GTests.
Previously you already added them.

…rence on a repeated pair

Description of the change:

ChFi2d_Builder::AddChamfer(const TopoDS_Edge& E1, const TopoDS_Edge& E2, double D1, double D2)
calls ChFi2d::FindConnectedEdges and dereferences the two edges it returns without checking the
returned status first. FindConnectedEdges leaves both edges null on every failure path, and a
second call naming the same edge pair hits exactly that: the pair's shared vertex is removed from
the face's wire by the first call's own BuildNewWire, so the second call's lookup fails and the
two null edges it returns reach ComputeChamfer unchecked.

Adds the same status check the sibling overload, AddChamfer(const TopoDS_Edge& E, const
TopoDS_Vertex& V, double D, double Ang), already has immediately after the identical
FindConnectedEdges call. chamfer is the default-constructed null edge this function already
returns on its other refusal paths, so this reuses the existing 'declined' signal rather than
introducing a new one.

Related issue: Fixes Open-Cascade-SAS#1431.

Tests:

New GTest in src/ModelingAlgorithms/TKFillet/GTests/BRepFilletAPI_MakeFillet2d_Test.cxx, calling
AddChamfer twice with the identical edge pair through the public API the crash was reported
against. Verified both ways: the current pinned kernel (predates this fix) SIGSEGVs on the second
call (exit 139); linked with the patched translation unit ahead of the archive, the same call
returns a null edge with Status() == ChFi2d_ConnexionError, matching the sibling overload's own
answer for an unconnected vertex, and the test passes.

How Has This Been Tested?

1. Standalone repro: a rectangular planar face, BRepFilletAPI_MakeFillet2d::AddChamfer called
   twice with the identical edge pair. On stock master, the second call SIGSEGVs 100% of the time
   (ComputeChamfer, both edges null).
2. Debug (-O0) single-TU override-link (this file compiled standalone and linked before the OCCT
   static archive, so the linker resolves this TU's symbols from the override): before the patch,
   the second call crashes; after, it returns a null edge with Status() == ChFi2d_ConnexionError.
3. The first call in both cases is unaffected: Status() == ChFi2d_IsDone, non-null edge, same
   geometry before and after.
4. New GTest exercises both directions directly (see above).
5. clang-format clean on both touched/added files.
@gsdali
gsdali force-pushed the fix/705-chfi2d-addchamfer-repeated-pair branch from 75fb65b to 50b1018 Compare August 10, 2026 23:56
@gsdali

gsdali commented Aug 10, 2026

Copy link
Copy Markdown
Contributor Author

Thanks — pushed a GTest.

BRepFilletAPI_MakeFillet2d_Test.cxx in src/ModelingAlgorithms/TKFillet/GTests/, calling AddChamfer twice with the identical edge pair through the same public API the original crash was reported against. Verified both directions before pushing: linked with the guard removed, the second call SIGSEGVs (exit 139); linked with the fix, it returns a null edge with Status() == ChFi2d_ConnexionError, matching the sibling overload's existing answer for an unconnected vertex, and the test passes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

ChFi2d_Builder::AddChamfer(edge, edge, ...) SIGSEGVs on a repeated edge pair (unchecked FindConnectedEdges status)

2 participants