bc20b034ff8a33abe6ede666a897724eb5e4fb30

Author
TheEdgeOfRage <git@theedgeofrage.com>
Committer
TheEdgeOfRage <git@theedgeofrage.com>
Date

Message

Don't flag negative glob secrets on the static matcher

Diff

 1diff --git a/src/core/deterministic.ts b/src/core/deterministic.ts
 2index 63e4aa2c374488f346b7e70acd8004b63ce3d338..2227aa0b3f2ba878fbd044bf4d0b8fbd6e4ea59d 100644
 3--- a/src/core/deterministic.ts
 4+++ b/src/core/deterministic.ts
 5@@ -317,6 +317,7 @@ function searchPaths(program: string, args: string[]): ArgumentRoles {
 6   const positional: string[] = [];
 7   const expressionOptions = new Set(["-e", "--regexp", "-f", "--file"]);
 8   const fileOptions = new Set(["-f", "--file", "--include", "-g", "--glob", "--iglob"]);
 9+  const globOptions = new Set(["--include", "-g", "--glob", "--iglob"]);
10   const flags = new Set([
11     "--files",
12     "--hidden",
13@@ -412,7 +413,11 @@ function searchPaths(program: string, args: string[]): ArgumentRoles {
14       const value = equals < 0 ? args[++index] : arg.slice(equals + 1);
15       if (value === undefined) return { paths, review: true };
16       if (expressionOptions.has(option)) expression = true;
17-      if (fileOptions.has(option) || option === "--exclude-from") paths.push(value);
18+      if (
19+        (fileOptions.has(option) || option === "--exclude-from") &&
20+        !(globOptions.has(option) && value.startsWith("!"))
21+      )
22+        paths.push(value);
23       continue;
24     }
25     if (arg.startsWith("--") && !flags.has(arg)) return { paths, review: true };
26@@ -427,7 +432,7 @@ function searchPaths(program: string, args: string[]): ArgumentRoles {
27         const value = arg.slice(offset + 1) || args[++index];
28         if (value === undefined) return { paths, review: true };
29         if (expressionOptions.has(flag)) expression = true;
30-        if (fileOptions.has(flag)) paths.push(value);
31+        if (fileOptions.has(flag) && !(globOptions.has(flag) && value.startsWith("!"))) paths.push(value);
32         break;
33       }
34     }
35diff --git a/test/core/deterministic.test.ts b/test/core/deterministic.test.ts
36index 82e7874cd5cfaa4a0d046379d6ff81c19305924a..9bf8dfb14d59c6542a8df350de5fc37d9590af1d 100644
37--- a/test/core/deterministic.test.ts
38+++ b/test/core/deterministic.test.ts
39@@ -56,6 +56,7 @@ const allowed = [
40   "grep -r needle",
41   "rg -e / safe",
42   "rg --glob / needle safe",
43+  "rg -n --glob '!**/secrets/**' --glob '!**/.env' needle safe",
44   "docker compose ps --all",
45   "systemctl --user is-active pi.service",
46   "echo value > output.txt",
47@@ -95,6 +96,7 @@ const asks = [
48   'cat .e"nv"',
49   "cat ~/.ssh/id_ed25519",
50   "rg -f .env README.md",
51+  "rg --glob '**/.env' needle safe",
52   "jq --rawfile data .env '.'",
53   "git commit -F.env",
54   "unknown-tool .env",