One StoreFileName in Core: no id collisions, no '..' escape #11

Merged
aqua merged 5 commits from aqua/safe-filename-collide-dotdot into main 2026-11-07 10:39:10 +00:00

2026-11-07

Aqua
StoreFileName.Combine: batch ids from the command line cannot leave the artifact root
IpaTrialWorker song-score took --batch-id raw into Path.Combine; the orchestrator
sites share the new Combine. Tests cover traversal and absolute batch ids and the
underscore on device stems (nul.x, LPT1.x); drop the double From on the emitter name.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 10:33:47 +00:00
Aqua
StoreFileName: device stems no longer survive as the stem; IpaTrialWorker paths use it
"nul.x" was rewritten to "nul.x-<hash>", whose stem is still NUL on Windows;
rewritten device names now get a leading underscore, and the test asserts the
stem is not reserved. IpaTrialWorker candidate directories go through
StoreFileName.From; its remaining SafeName only slugs uuid-suffixed record ids.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 09:54:00 +00:00
Aqua
StoreFileName: route IpaTrialOrchestrator and FaustCompiler through it; daemon test uses ".."
Nibu's review at abfc816: the daemon test passed against the old sanitizer
because "../../escape" never escaped there; the bare ".." did. IpaTrialOrchestrator
(SafeName, raw BatchId in Path.Combine) and FaustCompiler.SafeArtifactName were
second owners of the same decision.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 09:29:43 +00:00

2026-11-06

Aqua
StoreFileName: close review findings (collisions, case, device stems, length, renderId)
- Pass-through ids may not end in "-<16 hex>", so a rewritten name fed back as an id cannot alias it; hash widened 32 -> 64 bits.
- Ids with uppercase are rewritten (case-insensitive filesystems).
- Windows device stems (CON PRN AUX NUL COM0-9 LPT0-9, any extension) are rewritten.
- Stem capped at 100 chars; longer ids carry the hash.
- Daemon samples/ write now goes through StoreFileName.From(renderId).
- Tests: rewritten-as-id, case-only, device stems, overlong; daemon test uses a compiling patch so the samples/ write is reached when Faust is present.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-06 20:00:30 +00:00
Aqua
One StoreFileName in Core: no id collisions, no '..' escape
The daemon and native-runtime SafeFileName copies sanitised differently:
the daemon mapped a/b, a b, a:b and a-b to the same name (a later patch
overwrote an earlier artifact) and returned ".." unchanged, so a
sessionId or runId of ".." resolved one directory above the store.

Replace both with AquaSynth.Dsl.StoreFileName.From. Ids within
[A-Za-z0-9._-] pass through; any other id is sanitised and suffixed with
the first 8 hex of SHA-256 of the original. Empty, "." and all-dot ids
are refused (ArgumentException).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-06 18:29:25 +00:00