Commit Graph
4 Commits
Author SHA1 Message Date
Matt 78f80143d5 fix: hold the sketch caps at design load and bound the solver per component
Nothing on the load path checked a sketch's size, and every sketch in the
timeline is solved when a design opens. The solver sizes its dense matrices by
the connected component, so a 30 MB file with 200,000 chained points asked the
allocator for terabytes and the process aborted, which no panic guard can
intercept.

Reject an oversized sketch while the design is still raw JSON, so the typed
arrays are never built, and refuse a connected component with more variables
than fits in a bounded matrix: that component now reports a failed solve and
leaves its geometry alone. 10,000 chained points went from 9.6 GB and 25
seconds to a failed solve in well under a second.

Fixes #145

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
(cherry picked from commit 04abbf95c26f68c7d0a126ed9e2827049f593361)
2026-10-11 08:22:11 -07:00
Matt b5fb86f245 fix: bound four unbounded expansions in STEP and IGES import
Each of these asks the allocator for tens of gigabytes, or runs for hours, from
a file of a few kilobytes to a few megabytes. An allocation failure is an abort,
so no panic guard can report it and the user's unsaved work is gone.

- IGES composite curves (102) name their children by pointer, and a tree whose
  every node names the same child twice fans out to 2^30 leaf visits under the
  depth cap. Count the entities visited and the segments produced against one
  budget, since a node that yields no segment trips no bound on the output, and
  refuse a composite curve that contains itself.
- IGES directory entries could all name the same parameter range, each
  materialising it as its own string and token list. Keep the total text
  proportional to the parameter section the file carries.
- STEP knot multiplicities were expanded into one value each before the knot
  count was compared with the control points: 20 million knots of multiplicity
  64 built a 10 GB vector only to be rejected. Check the sum first.
- One STEP face could list any number of boundary loops, each cloning its edge
  handles into a new wire that the face extent then samples. Cap the loops and
  the edges they hold; 100,000 bounds went from 2.1 GB to an immediate error.

Also guard the IGES translation, which was the one importer stage outside every
panic guard, keep the vertex-sewing bucket key clear of the overflow its
neighbour lookup caused for coordinates near f64's range, and count how often a
loop passes each vertex once instead of once per edge.

Fixes #146

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
(cherry picked from commit c32792b71c76d74348ad5002d8d2da870937e58e)
2026-10-11 08:22:07 -07:00
Matt a03e4b9413 fix: budget the work 3MF and DXF import does, not only its output
3MF: flatten budgeted triangles but copied the whole vertex array for every
placement, so an object with 100,000 vertices and one triangle placed by 500
build items reached 6.8 GB resident, and 10,000 items (still a ~200 KB file)
asked for about 140 GB and aborted on the allocation. Copy only the vertices
the triangles reach, keeping their relative order so an ordinary mesh is
numbered as it was in the file.

DXF: every bound in convert was on the geometry that comes out, and a block
that emits none tripped none of them. Six self-inserts in one empty block fan
out to 6^16 visits, and a 176-byte file never returned. Count entities visited
and array cells placed against a work budget, skip the array loop for a block
with no geometry, and bound the array size on its own.

Fixes #144

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
(cherry picked from commit 3bf3b68a1340d9bdef8dcefd6c4fb5a7cae6eec4)
2026-10-11 08:22:07 -07:00
Matt 0b5e15e2b9 fix: continue the plane depth count through model geometry
A construction plane built from model geometry resolves each of its sides
through the document again. That hop restarted the recursion depth at 0, so a
plane that is its own side never exceeded depth 1 and the 32-level cap never
fired: a ~600-byte design file recursed until the stack overflowed and the
process aborted, which no panic guard can intercept.

Carry the depth on the construction context so the geometry arms continue the
caller's count instead of restarting it.

Fixes #143

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
(cherry picked from commit 4bca1d49f27dfe9ef0140132746e1c7415daba8e)
2026-10-11 08:22:07 -07:00