Files
solvecraft/plan/upstream-issues
2026-10-30 18:16:19 -04:00
..

Upstream SMLib issues (one file each)

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-ffi surface_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-ffi primitive_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-ffi intersect_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.