Ports tangency-labs/smlib@2223108 behind
Kernel::fixes.fillet_mitre_gap_patch: SmFilletNx2Corner::AdjustTopology
builds the concave corner's topology (AdjustConcaveCornerTopology) for a
bevel at a face's concave corner whose rails meet the side edge at two
places, and CreateCornerPatch fills only that gap (m_bBevelGapPatch).
Tested on the fork's sloped basin and SolidCraft's 1080 basin cases.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MNXLXj2sJf943y2dDF36Vy
One file per upstream C++ defect, so parallel PRs never conflict. Never append to a
shared file. The rules, fields, severity order and numbering are below (from the former
archive). The site (site/build.py) renders every file here, in name order.
Name:<ID>--<short-slug>.md, e.g. WR-262--extrusion-drop-point-fast.md. The ID
takes the next free number in its series (UB-, HANG-, ND-, WR-, DOC-) across
this directory. If two PRs pick the same number, whoever merges second renumbers theirs
(the site flags duplicates).
Content:
#### WR-262. One-line title [PSIRT if file input reaches memory corruption]
- **Severity:** Wrong result
- **Area:** Surfaces and volumes
- **Location:** `source/SMLib/src/File.cpp:123`, `Function` (def. `:100`).
- **What happens:** ...
- **Trigger:** ...
- **How found:** generated difftest case
- **Confirmed:** yes, case `gen0042` of `unit.id`
Severity is one of Crash / undefined behaviour, Hang, Nondeterminism,
Wrong result, Docs. Area is free text, ideally one of the areas already used
here (grep -rh '^- \*\*Area:' plan/upstream-issues/ | sort | uniq -c).
Updates (now confirmed, fixed upstream, renumbered, withdrawn) are addenda, not
edits: a new file <ID>--addendum-<YYYY-MM-DD>-<slug>.md starting with
Updates: <ID> and what changed. Records are never edited after they merge.
Older references to plan/upstream-issues.md IDs (and plan/findings.md: <heading>): grep the heading or ID under this directory
(grep -rl '^#### UB-35\.' plan/upstream-issues/).
History
Until 2026-10-25 the issues were #### entries of one shared file,
plan/upstream-issues.md, grouped under ## <severity> and ### <area> headings. On
2026-10-25 scripts/split_archives.py split it into one file per entry here and deleted
it; python3 -I scripts/split_archives.py check proves the split lossless. Each file
keeps the #### line verbatim, adds - **Severity:** and - **Area:** from the
headings it stood under, then the entry verbatim. Entries filed after the ## Docs
section, under the two headings that were not severities, take the severity of their ID
series and an empty area (or the ### heading under them). The second entry for an ID
already used has a --dup2 name suffix; its heading is unchanged. Entries without a
numeric ID are named UB-new--, UB-unnumbered--, ISSUE-489-- and UNNUMBERED--. A
hang report that had a ## heading and no #### entry is
HANG-unnumbered--createlinearsweep-negative-full-circle-distance-does-not.md (not
rendered on the site, as before). The archive's text outside the entries follows
verbatim, except its "Frozen archive" notice; "here" in it means the archive.
Defects and hazards in the upstream C++ (source/SMLib, source/SM_API) found while
porting it to Rust. Problems only: porting notes, harness details and Rust-side choices
stay in plan/findings.md. Behaviour that is odd but plausibly intended is left out.
Upstream commit:c9c5979 (NVIDIA usd-brep). Paths are relative to the upstream
root. Line numbers were checked against that commit.
Security. Entries marked [PSIRT] are crafted-file memory or stack exhaustion,
or out-of-bounds or uninitialised reads that file input can reach. Per upstream
SECURITY.md, report these to NVIDIA PSIRT (psirt@nvidia.com or the web form), not as
public GitHub issues. The other out-of-bounds entries need a bad argument from the
calling code. Whoever files them should still decide whether they count as security
issues.
Fields.
How found: "read during porting" means source reading only. The other values are
"generated difftest case", "adversarial / edge-case fixture", or "crash in the C++
reference run" (the difftest harness linking the upstream build).
Confirmed:yes only when a C++ run showed the behaviour: a crash, or a named
difftest case or fixture that compares against it. Otherwise no. In most "no"
cases the harness deliberately keeps that input away from the C++ side.
Build. The reference build is the upstream release configuration (-O2, no
SM_DEBUG_CODE, SM_USE_OLDTOL) with -ffp-contract=off, on x86-64 Linux / LP64.
Severity order: crash/UB, hang, nondeterminism, wrong result, docs. Entries are grouped
by area within each severity, so IDs are in order within each area but not across a
whole severity.
Numbering. A new entry takes the next free number in its series (UB-, HANG-,
ND-, WR-, DOC-) at the moment its PR merges. If another PR took that number in the
meantime, whoever merges renumbers the new entry and every reference to it (here, in
plan/findings.md, plan/modules.toml and code comments). Numbers are not reused.
Note: duplicate IDs (2026-10-23)
Parallel PRs gave six IDs to more than one entry. They are not renumbered, because code
comments, shims, unit notes, findings and PRs already cite them; when citing one of these
IDs, add the function name so the entry is unambiguous. Each entry, by its section and
title (other references in the repo in brackets):
UB-100: (a) Surfaces and volumes, SmDerivSurfDefinition::GetSampleValues missing
tangent reference [solidcore-ffisurface_surface_p6.rs, surface.surface_p6
notes, findings]; (b) Intersection, SmPolyBrep::CalculateBoundingBox null point array
for a pseudo box.
UB-185: (a) Topology, SmFilletVertex::CalcMateGeom unbounded recursion through a
cycle of mates [blend.fillet_geom_p3 notes, MAX_MATE_DEPTH]; (b) Numerical
integration (near the end of the file), fillet executive m_bIsInitialized
indeterminate before parameter setup [blend_fillet_executive_p2/p3 shims and FFI,
findings].
UB-204: (a) NLib: matrices and polynomials, SmMatrix(rows, cols) uninitialised
inline storage used by SmLocalSolveNd [difftest curve_curve_p9.rs, findings
(#94)]; (b) Surfaces and volumes, SmFilletSolver::GetSurface unbounded recursion
through the geometry set [findings, blend.fillet_solver_p1 pseudo B-rep entry].
UB-210: (a) Topology, SmBrep::DeleteEdge reads pSurvF outside the merge branch
[topology/brep/p4.rs, topology.brep_p4 notes]; (b) Topology,
SmFilletEdge::CalcFilletIntFillet reads the context of a missing fillet corner
[blend_fillet_geom_p3 shim, runner and fixtures, blend.fillet_geom_p3 notes].
UB-238 (four entries): (a) NLib: knots and basis functions,
SmBSplineCurve::CreateCanonical heap corruption for a NaN knot [solidcore-ffiprimitive_api_curves.rs, fuzz corpus]; (b) Spatial structures and small geometry,
vertex/vertex and edge/edge topology solvers dereference NULL in a release
SM_ASSERT [solidcore-ffiintersect_topology_solver_p1.rs]; (c) Curves,
SetIntersectionCurveThroughPoint builds UV trim curves from the address of a pointer
slot; (d) Topology, SmFilletGeom::MakeRailEdgeuse leaves a deleted vertex use linked
in the fillet vertex [blend_fillet_geom_p5 shim and FFI, blend.fillet_geom_p5
notes, findings].
WR-190: (a) Topology, attributes, solvers, SmFilletSolver::RecordFilletError
reports rail 0 for rail 1 [blend/fillet_solver/p2.rs]; (b) Curves,
SmFilletEdge::CalcBlendingRail builds its Hermite fallback as a degree-2 curve
[blend/fillet_geom/p6.rs].
New entries take the next free number after the highest in their series, as the
Numbering paragraph at the top says.