diff --git a/packages/runtime/src/band-server.ts b/packages/runtime/src/band-server.ts index 211c568..bf5232b 100644 --- a/packages/runtime/src/band-server.ts +++ b/packages/runtime/src/band-server.ts @@ -21,6 +21,7 @@ import { Hono } from "hono"; import { createHash } from "crypto"; +import { randomId } from "./random-id"; const BAND_RUNNER_USER = "band-runner"; let executing = false; @@ -136,10 +137,6 @@ function shellIgnoreError(cmd: string): void { Bun.spawnSync(["sudo", "bash", "-c", cmd]); } -function randomId(): string { - return Math.random().toString(36).slice(2, 10); -} - /** Reject values containing shell metacharacters. Used for any band-config value interpolated into shell commands. */ function shellSafe(value: string, label: string): string { if (/[;`$(){}|&<>!\\"\n\r]/.test(value)) { diff --git a/packages/runtime/src/random-id.ts b/packages/runtime/src/random-id.ts new file mode 100644 index 0000000..b173033 --- /dev/null +++ b/packages/runtime/src/random-id.ts @@ -0,0 +1,5 @@ +import { randomBytes } from "crypto"; + +export function randomId(): string { + return randomBytes(8).toString("hex"); +} diff --git a/packages/runtime/test/unit/random-id.test.ts b/packages/runtime/test/unit/random-id.test.ts new file mode 100644 index 0000000..f272c14 --- /dev/null +++ b/packages/runtime/test/unit/random-id.test.ts @@ -0,0 +1,21 @@ +import { describe, expect, test } from "bun:test"; +import { randomId } from "../../src/random-id"; + +describe("randomId", () => { + test("generates 16-character hex IDs", () => { + expect(randomId()).toMatch(/^[0-9a-f]{16}$/); + }); + + test("does not use Math.random", () => { + const originalRandom = Math.random; + Math.random = () => { + throw new Error("Math.random should not be used for workdir IDs"); + }; + + try { + expect(randomId()).toMatch(/^[0-9a-f]{16}$/); + } finally { + Math.random = originalRandom; + } + }); +});