Shape Healing - guard the null Context() in ShapeFix_Face::FixPeriodicDegenerated#1380
Open
gsdali wants to merge 1 commit into
Open
Conversation
gsdali
force-pushed
the
fix/317-shapefix-face-null-context-periodicdegenerated
branch
from
July 19, 2026 12:00
eac4127 to
920c07a
Compare
…cDegenerated ShapeFix_Face::Perform SIGSEGVs healing a face whose sole boundary wire is a single closed edge belting the full period of a Geom_ConicalSurface, positioned so the apex sits outside the wire's V range. FixPeriodicDegenerated finalizes with an unconditional Context()->Replace(myFace, myResult); every other Context()->Replace call site in this file guards Context().IsNull() first (the function's own top even does, for Context()->Apply()) -- this one didn't, so a bare "ShapeFix_Face fixer(face); fixer.Perform();" (the ordinary usage, no SetContext call) null-derefs. Restores the same guard used everywhere else in the file. Added GTests: NoCrashOnPeriodicConicalSingleWire (crashes on master, survives with this patch) and ValidFaceOnPeriodicConicalSingleWireWithContext (same input healed with a context produces a genuinely valid face -- the guard only skips recording a replacement that has nowhere to go, it does not skip building the degenerate apex edge itself). Reported downstream and isolated at SecondMouseAU/OCCTSwift#317.
gsdali
force-pushed
the
fix/317-shapefix-face-null-context-periodicdegenerated
branch
from
July 19, 2026 12:10
920c07a to
71b4cf6
Compare
dpasukhi
self-requested a review
July 22, 2026 14:12
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1378.
Problem
ShapeFix_Face::Perform()SIGSEGVs healing a face whose sole boundary wire is a single closed edgebelting the full 2π period of a
Geom_ConicalSurface(positioned so the apex sits outside thewire's V range) — the exact case
FixPeriodicDegenerated()exists to patch in a degenerate apexedge for. Only the plain, most common usage crashes:
ShapeFix_Face fixer(face); fixer.Perform();,with no explicit
SetContext()call.Root cause
FixPeriodicDegenerated()builds the degenerate apex edge/wire, assembles a new face from theoriginal wire plus the apex wire, and finalizes:
myResult = aNewFace; Context()->Replace(myFace, myResult);Every other
Context()->Replacecall site in this file — eleven of them — guards against a nullContext()first (either a plainif (!Context().IsNull()), or a lazySetContext(new ShapeBuild_ReShape)when null).FixPeriodicDegeneratedeven checksContext().IsNull()at thetop of the function before calling
Context()->Apply()— but the check is missing at thebottom.
Context()returnsShapeFix_Root::myContext, left null by the base constructor and setonly by an explicit
SetContext()call — which the ordinary constructionShapeFix_Face fixer(face); fixer.Perform();never makes. Any caller healing a lone periodic-conical wire this waynull-derefs.
Fix
The same guard used at every other call site in the file — only replace in the context if there is
one to replace in.
Reproducer / test
Crashes on current master; fixed here. Added GTest
ShapeFix_FaceTest.NoCrashOnPeriodicConicalSingleWire.Validation
Diagnosed with a custom
backtrace_symbols_fdSIGSEGVhandler (lldb/core dumps unavailable inthe diagnosing sandbox), pinpointing the crash to
ShapeFix_Face::FixPeriodicDegenerated; an-O0single-TU override-link (compiling just the patched
.cxxand linking it before the archive)confirmed every statement in the function up to the final
Context()->Replacecompletes normally,and that call is specifically where it faults. Both the minimal 8-point synthetic reproducer above
and a 10-point closed curve fit through real mesh-derived rivet-rim points (the case this was
originally surfaced from) crash 100% of the time on stock
V8_0_0_p1and survive with this patch,returning a valid healed face (
BRepCheck_Analyzer::IsValid() == true).Reported downstream and isolated at SecondMouseAU/OCCTSwift#317.