diff --git a/bin/moshcode.mjs b/bin/moshcode.mjs index cb500cdb..775ef2be 100755 --- a/bin/moshcode.mjs +++ b/bin/moshcode.mjs @@ -49,7 +49,7 @@ function parseMax(value) { throw new Error(`moshcode run: --max must be a positive integer, got ${JSON.stringify(value)}`); } const max = Number(value); - if (!Number.isInteger(max) || max < 1) { + if (!Number.isSafeInteger(max) || max < 1) { throw new Error(`moshcode run: --max must be a positive integer, got ${JSON.stringify(value)}`); } return max; diff --git a/src/tui.mjs b/src/tui.mjs index ecbdf78c..e8a7bc75 100644 --- a/src/tui.mjs +++ b/src/tui.mjs @@ -325,11 +325,11 @@ async function runFile(args) { const a = args[i]; if (a === "--max" || a === "-n") { const v = Number(args[++i]); - if (!Number.isInteger(v) || v < 1) { console.log(err(`--max needs a positive integer`)); return; } + if (!Number.isSafeInteger(v) || v < 1) { console.log(err(`--max needs a positive integer`)); return; } max = v; } else if (a.startsWith("--max=")) { const v = Number(a.slice("--max=".length)); - if (!Number.isInteger(v) || v < 1) { console.log(err(`--max needs a positive integer`)); return; } + if (!Number.isSafeInteger(v) || v < 1) { console.log(err(`--max needs a positive integer`)); return; } max = v; } else if (a === "--dry-run") { dryRun = true; diff --git a/test/run-options.test.mjs b/test/run-options.test.mjs index a0355965..36f2245f 100644 --- a/test/run-options.test.mjs +++ b/test/run-options.test.mjs @@ -83,7 +83,7 @@ test("run accepts equals-form max option", async () => { }); test("run rejects non-decimal max values", async () => { - for (const value of ["1e1", "0x2"]) { + for (const value of ["1e1", "0x2", "9007199254740992"]) { const result = await run([`--max=${value}`, "--dry-run"]); assert.equal(result.status, 1); diff --git a/test/tui.test.mjs b/test/tui.test.mjs index 999d6d56..f52186f8 100644 --- a/test/tui.test.mjs +++ b/test/tui.test.mjs @@ -59,6 +59,14 @@ test("TUI /run rejects unknown options before reading a script file", async () = assert.doesNotMatch(result.stdout, /can't read --dryrun/); }); +test("TUI /run rejects unsafe iteration limits", async () => { + const result = await runTui("/run --max=9007199254740992\n/quit\n"); + + assert.equal(result.status, 0); + assert.match(result.stdout, /--max needs a positive integer/); + assert.doesNotMatch(result.stdout, /usage: \/run/); +}); + test("TUI /run passes positional args through to moshscript argv", () => { const dir = mkdtempSync(join(tmpdir(), "moshcode-tui-")); mkdirSync(join(dir, "space dir"));