first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,58 @@
# 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.