# Path sanitisation ## Purpose `sanitizePath` is the single boundary check every method that accepts a filesystem path passes through before invoking `FsLike`. It enforces three rules — non-empty strings, no null bytes, no `..` traversal outside a configured `rootDir` — and turns every failure into a stable `AudioEngineServerError` carrying code `AUDIO_ENGINE_SERVER.INVALID_PATH`. Co-located helpers `isHttpUrl` (for URL inputs that bypass filesystem sanitisation) and `checkAborted` (for `AbortSignal` short-circuits) keep the I/O entry points small. ## Features - Empty / null-byte / `..` traversal rejection with a single dotted code. - Optional `rootDir` jail — when supplied, every path resolves under it and absolute inputs outside the boundary are rejected. - `isHttpUrl` lets `FileSourceAdapter.load` route URL inputs through `fetch` without filesystem sanitisation. - `checkAborted` short-circuits any operation whose `AbortSignal` is already in the aborted state before any filesystem call is issued. ## Usage: Basic ```ts import { sanitizePath } from "@suaveplan/audio-engine-server"; const safe = sanitizePath("./input.wav", "/var/uploads"); // safe === "/var/uploads/input.wav" ``` ## Usage: Advanced ```ts import { sanitizePath, isHttpUrl, checkAborted } from "@suaveplan/audio-engine-server"; function loadAny(input: string, signal?: AbortSignal) { checkAborted(signal); if (isHttpUrl(input)) return fetchAndDecode(input); return readAndDecode(sanitizePath(input, process.env.AUDIO_ROOT)); } ``` ## API Reference - `sanitizePath(path: string, rootDir?: string): string` — returns the resolved absolute path when `rootDir` is given, else the input unchanged. - `isHttpUrl(value: string): boolean` — true for any `http`/`https` URL. - `checkAborted(signal: AbortSignal | undefined): void` — throws `AUDIO_ENGINE_SERVER.ABORTED` when `signal.aborted` is true. ## Implementation Notes The traversal check resolves both `rootDir` and the candidate through `node:path.resolve` so platform-specific separators (`/` and `\`) and double-dot sequences are normalised before comparison. The `.startsWith` guard uses a trailing separator so `"/var/uploads-evil"` cannot satisfy the `"/var/uploads"` root.