Jscad Stl Validator
STL file validator — checks triangle count, degenerate faces, bounding box
2026.08.01.1
Fixes the HIGH-severity path-traversal / arbitrary-file-read finding (LB1) in
validateFile, tracked in the LOCAL jscad-stl-validator-latent-bugs
issue-lifecycle model (NEVER a swamp.club Lab issue). validateFile is an
operator-supplied-absolute-path method by design; this fix is defense in depth
for any future less-trusted exposure.
Behavior change: validateFile now rejects any filePath that is not
absolute, and any filePath containing a literal . or .. path segment —
previously such a path (e.g. a traversal-shaped path) was read verbatim with no
confinement at all. The traversal/absolute-path check runs BEFORE any filesystem
access, so a traversal attempt against a nonexistent target is still refused as
a policy violation, never silently masked by a "file not found" error.
Legitimate callers passing a clean absolute path (as shown in this README's
examples) are unaffected.
- Added
extensions/models/jscad/safe_path.ts— a new infrastructure guard,resolveStlPath, implementing the always-on checks above plus canonicalization viaDeno.realPath. The pure domain servicejscad/stl_validator.tsstays BYTE-FROZEN; path safety is an infrastructure concern, kept out of the domain service. - Added an OPT-IN
allowedRootsglobal argument (default[], read viacontext.globalArgs— never the per-call arguments) that confinesvalidateFileto one or more operator-set root directories, using canonicalized (Deno.realPath'd) separator-boundary prefix matching so a sibling directory sharing a name prefix (/rootFOOvs./root) or a symlinked root cannot be mistaken for containment. EmptyallowedRoots(the default) preserves the historical unconfined contract. extensions/models/jscad_stl_validator.ts:validateFilenow resolvesargs.filePaththroughresolveStlPathbefore callingDeno.readFile. Error messages still key to the ORIGINALargs.filePath(not the canonicalized path), so the existing missing-file/directory-pathCannot read "<path>"throw-tests stay green; policy violations get a distinctRefusing to read "<path>": ...message. Modelversionbumped to2026.08.01.1.manifest.yamlversion bumped to2026.08.01.1in sync; addedextensions/models/jscad/safe_path_test.tstoadditionalFiles.deno.json'schecktask extended to typecheckjscad/safe_path.ts+jscad/safe_path_test.ts.- Test suite: added
extensions/models/jscad/safe_path_test.ts(11 unit tests covering reject-relative, reject-./..-segment including the nonexistent-traversal-target ordering guarantee, accept-clean-absolute,allowedRootsaccept/reject, separator-boundary/rootFOO-vs-/root, symlink-escape rejection, and root/target canonicalization). Flipped the LB1 "../traversal path read verbatim" pin injscad_stl_validator_adversarial_test.tsto assert rejection; relabeled the "no base dir, two unrelated roots both succeed" pin from a HIGH bug-pin to aregression:-prefixed default-contract test (still asserts both calls succeed — that is the intended behavior whenallowedRootsis not configured). AddedallowedRootsaccept/deny cases plus a test proving a smuggled per-callargs.allowedRootshas no effect tojscad_stl_validator_methods_test.ts. All prior binary/ASCII happy paths and the missing-file/directory-path throw-path tests are unchanged and still green. - README.md: documented the
validateFileoperator-trust boundary and the opt-inallowedRootsconfinement, including the residual "report reflects file bytes" oracle risk to keep in mind when narrowingallowedRoots. - LB2/LB3/LB4/LB5 remain pinned as characterized (not fixed) latent bugs — out
of scope for this fix, tracked in the same issue-lifecycle model. The sibling
jscad-stl-slicerextension shares the same unconfined-path pattern; deliberately NOT fixed here — tracked as its own follow-up.
Global Arguments
| Argument | Type | Description |
|---|---|---|
| allowedRoots | array | Optional operator-set confinement roots for validateFile. When |
| Argument | Type | Description |
|---|---|---|
| cadModelName | string | Name of the @magistr/jscad-cad model whose stored output STL to validate |
| version? | number | Data version to validate (defaults to latest) |
| Argument | Type | Description |
|---|---|---|
| filePath | string | Absolute path to the STL file to validate |
Resources
Release 2026.07.16.2 — align model versions with manifests
Maintenance release across the @magistr extensions. For most packages this
carries no functional change: the only edit is the model's version: field,
brought back in line with its manifest version so the published model type
version and the package version no longer drift.
Functional changes in this release are limited to:
anime-cron: normalizeTitle now strips a ": subtitle" suffix and a trailing parenthesized year before comparison, fixing dedup false-misses where the torrent title carries a subtitle or year that the AniList romaji does not.
arckit: first publish. Standalone ArcKit port — a 12-phase architecture governance state machine with 65 bundled templates, driven by a bundled skill.
Also tracks three extensions (kaiten, observability-agent, music-library) that previously existed only as untracked working-tree directories, recovered from stashes.
Added 1, removed 1 models
Merge pull request #5 from umag/extensions/jscad-stl-pair
extensions: add 15 more @magistr extensions + auto-discover CI
- Has README or module doc2/2earned
- README has a code example1/1earned
- README is substantive1/1earned
- Most symbols documented1/1earned
- No slow types (deprecated)1/1earned
- Dependencies pass trust audit2/2earned
- Has description1/1earned
- Platform support declared (or universal)2/2earned
- License declared1/1earned
- Verified public repository2/2earned