From 5d4afa92cd6a110e5792a908bcd33b2dbe088b77 Mon Sep 17 00:00:00 2001 From: reyanthony062001-ops Date: Wed, 15 Jul 2026 08:02:59 +0000 Subject: [PATCH] fix(miner): stop hooks check --tool/--input consuming an adjacent flag as their value parseDenyCheckArgs took the next token unconditionally for --tool/--name and --input, so `hooks check --tool --input '{}'` silently set options.tool = "--input" and then fell through to the generic usage string on the following token, instead of the specific "Missing value for --tool." error every sibling flag parser in this package gives for the same mistake. Adds the same `!value || value.startsWith("-")` guard already used by attempt-cli.js and claim-ledger-cli.js to both value-consuming branches, rejecting --input's value before it is JSON-parsed. Messages reuse this file's existing conventions ("Missing value for --tool." / "Missing value for --input."). Closes #5833 --- packages/loopover-miner/lib/deny-check.js | 6 ++++-- test/unit/miner-cli-deny-check.test.ts | 12 ++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/packages/loopover-miner/lib/deny-check.js b/packages/loopover-miner/lib/deny-check.js index dda33c14cb..d8bd347d10 100644 --- a/packages/loopover-miner/lib/deny-check.js +++ b/packages/loopover-miner/lib/deny-check.js @@ -34,12 +34,14 @@ export function parseDenyCheckArgs(args) { } if (token === "--tool" || token === "--name") { const tool = args[++index]; - if (!tool) return { error: "Missing value for --tool." }; + if (!tool || tool.startsWith("-")) return { error: "Missing value for --tool." }; options.tool = tool; continue; } if (token === "--input") { - const parsed = parseToolInput(args[++index]); + const raw = args[++index]; + if (!raw || raw.startsWith("-")) return { error: "Missing value for --input." }; + const parsed = parseToolInput(raw); if ("error" in parsed) return { error: parsed.error }; options.input = parsed.value; continue; diff --git a/test/unit/miner-cli-deny-check.test.ts b/test/unit/miner-cli-deny-check.test.ts index 9a09e1c36c..5c5543e2ab 100644 --- a/test/unit/miner-cli-deny-check.test.ts +++ b/test/unit/miner-cli-deny-check.test.ts @@ -27,6 +27,18 @@ describe("loopover-miner hooks check command", () => { }); }); + it("parseDenyCheckArgs rejects a flag consumed as another flag's value (#5833)", () => { + // --tool/--input must not swallow an adjacent flag as their value; each reports the specific + // "Missing value" error rather than falling through to the generic usage string. + expect(parseDenyCheckArgs(["--tool"])).toEqual({ error: "Missing value for --tool." }); + expect(parseDenyCheckArgs(["--tool", "--input", "{}"])).toEqual({ error: "Missing value for --tool." }); + expect(parseDenyCheckArgs(["--name", "--json"])).toEqual({ error: "Missing value for --tool." }); + expect(parseDenyCheckArgs(["--tool", "Write", "--input"])).toEqual({ error: "Missing value for --input." }); + expect(parseDenyCheckArgs(["--tool", "Write", "--input", "--json"])).toEqual({ + error: "Missing value for --input.", + }); + }); + it("runDenyCheck exits 1 when a built-in rule blocks the call", () => { const error = vi.spyOn(console, "error").mockImplementation(() => undefined); expect(