From eaf6fae5616dff0f1bcb7cebe4126b16750d50b1 Mon Sep 17 00:00:00 2001 From: aiirvizionz Date: Sat, 11 Jul 2026 10:34:02 -0600 Subject: [PATCH] Validate moshscript sleep durations --- src/commands.mjs | 6 +++++- test/commands.test.mjs | 12 ++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/commands.mjs b/src/commands.mjs index 7cacf74..e5c2211 100644 --- a/src/commands.mjs +++ b/src/commands.mjs @@ -65,7 +65,11 @@ export function defaultCommands() { // handy extras say: (ctx, args) => ctx.out(` 💬 ${args.join(" ")}`), sleep: async (_ctx, args) => { - const ms = Number(args[0] || 0); + const raw = args[0] ?? 0; + const ms = Number(raw); + if (!Number.isFinite(ms) || ms < 0) { + throw new Error(`moshscript: sleep(ms) requires a finite non-negative number, got ${JSON.stringify(raw)}`); + } if (ms > 0) await new Promise((r) => setTimeout(r, ms)); }, stop: (ctx, args) => { diff --git a/test/commands.test.mjs b/test/commands.test.mjs index 0ad9f08..79d4fdf 100644 --- a/test/commands.test.mjs +++ b/test/commands.test.mjs @@ -34,3 +34,15 @@ test("notify() still accepts message arguments", async () => { assert.equal(ctx.lines.length, 1); assert.match(ctx.lines[0], /hello there/); }); + +test("sleep accepts zero milliseconds", async () => { + await defaultCommands().sleep({}, [0]); +}); + +test("sleep rejects non-finite and negative durations", async () => { + const sleep = defaultCommands().sleep; + + await assert.rejects(() => sleep({}, ["forever"]), /finite non-negative number/); + await assert.rejects(() => sleep({}, ["Infinity"]), /finite non-negative number/); + await assert.rejects(() => sleep({}, [-1]), /finite non-negative number/); +});