mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-26 04:15:48 -06:00
fix: keep inline eval approvals one-shot [AI] (#112956)
* fix: classify inline eval interpreters * fix: cover inline eval flag variants * fix: handle snippet eval option aliases * fix: classify debugger and runtime callbacks * fix: tighten interpreter eval matching * fix: cover gdb early init eval flags * fix: cover bundled eval option forms * fix: cover gdb eval abbreviations * fix: cover iex and guile eval forms
This commit is contained in:
committed by
GitHub
parent
e3636852ba
commit
dc4c5887fa
@@ -61,6 +61,142 @@ describe("exec inline eval detection", () => {
|
||||
{ argv: ["php", "-E", "system('id');"], expected: "php -E" },
|
||||
{ argv: ["php", "-R", "system('id');"], expected: "php -R" },
|
||||
{ argv: ["Rscript", "-e", "system('id')"], expected: "rscript -e" },
|
||||
{ argv: ["julia", "-e", "run(`id`)"], expected: "julia -e" },
|
||||
{ argv: ["julia", "-erun(`id`)"], expected: "julia -e" },
|
||||
{ argv: ["julia", "--eval=run(`id`)"], expected: "julia --eval" },
|
||||
{ argv: ["julia", "-E", "VERSION"], expected: "julia -E" },
|
||||
{ argv: ["julia", "-EVERSION"], expected: "julia -E" },
|
||||
{ argv: ["elixir", "-e", 'System.cmd("id", [])'], expected: "elixir -e" },
|
||||
{ argv: ["elixir", '--eval=System.cmd("id", [])'], expected: "elixir --eval" },
|
||||
{
|
||||
argv: ["elixir", "--rpc-eval", "worker@127.0.0.1", 'System.cmd("id", [])'],
|
||||
expected: "elixir --rpc-eval",
|
||||
},
|
||||
{ argv: ["iex", "-e", 'System.cmd("id", [])'], expected: "iex -e" },
|
||||
{
|
||||
argv: ["iex", "--rpc-eval", "worker@127.0.0.1", 'System.cmd("id", [])'],
|
||||
expected: "iex --rpc-eval",
|
||||
},
|
||||
{ argv: ["guile", "-c", '(system "id")'], expected: "guile -c" },
|
||||
{ argv: ["guile", "-e", '(lambda args (system "id"))', "/dev/null"], expected: "guile -e" },
|
||||
{ argv: ["groovy", "-e", '"id".execute()'], expected: "groovy -e" },
|
||||
{ argv: ["groovy", '-e"id".execute()'], expected: "groovy -e" },
|
||||
{ argv: ["groovy", "-ne", '["id"].execute()'], expected: "groovy -e" },
|
||||
{ argv: ["groovy", "-pe", '["id"].execute()'], expected: "groovy -e" },
|
||||
{ argv: ["groovy", '-encoding:["id"].execute()'], expected: "groovy -e" },
|
||||
{ argv: ["scala", "-e", 'sys.process.Process("id").!'], expected: "scala -e" },
|
||||
{
|
||||
argv: ["scala", "--script-snippet", 'sys.process.Process("id").!'],
|
||||
expected: "scala --script-snippet",
|
||||
},
|
||||
{
|
||||
argv: ["scala-cli", "--script-snippet", 'sys.process.Process("id").!'],
|
||||
expected: "scala-cli --script-snippet",
|
||||
},
|
||||
{
|
||||
argv: ["scala", "--execute-script", 'sys.process.Process("id").!'],
|
||||
expected: "scala --execute-script",
|
||||
},
|
||||
{
|
||||
argv: ["scala", "--execute-sc=println(1)"],
|
||||
expected: "scala --execute-sc",
|
||||
},
|
||||
{
|
||||
argv: ["scala", "--execute-scala-script=println(1)"],
|
||||
expected: "scala --execute-scala-script",
|
||||
},
|
||||
{
|
||||
argv: ["scala", "--scala-snippet=println(1)"],
|
||||
expected: "scala --scala-snippet",
|
||||
},
|
||||
{
|
||||
argv: ["scala", "--execute-scala=println(1)"],
|
||||
expected: "scala --execute-scala",
|
||||
},
|
||||
{
|
||||
argv: ["scala", "--java-snippet", "class Main {}"],
|
||||
expected: "scala --java-snippet",
|
||||
},
|
||||
{
|
||||
argv: ["scala", "--execute-java=class Main {}"],
|
||||
expected: "scala --execute-java",
|
||||
},
|
||||
{
|
||||
argv: ["scala", "--markdown-snippet", "```scala\nprintln(1)\n```"],
|
||||
expected: "scala --markdown-snippet",
|
||||
},
|
||||
{
|
||||
argv: ["scala", "--md-snippet=```scala\nprintln(1)\n```"],
|
||||
expected: "scala --md-snippet",
|
||||
},
|
||||
{
|
||||
argv: ["scala", "--execute-markdown", "```scala\nprintln(1)\n```"],
|
||||
expected: "scala --execute-markdown",
|
||||
},
|
||||
{
|
||||
argv: ["scala", "--execute-md=```scala\nprintln(1)\n```"],
|
||||
expected: "scala --execute-md",
|
||||
},
|
||||
{ argv: ["clojure", "-e", '(clojure.java.shell/sh "id")'], expected: "clojure -e" },
|
||||
{ argv: ["clj", "--eval", "(println 1)"], expected: "clj --eval" },
|
||||
{ argv: ["raku", "-e", "run 'id'"], expected: "raku -e" },
|
||||
{ argv: ["raku", "-e say 1"], expected: "raku -e" },
|
||||
{ argv: ["raku", "-ne", "run 'id'"], expected: "raku -e" },
|
||||
{ argv: ["perl6", "-e", "run 'id'"], expected: "perl6 -e" },
|
||||
{ argv: ["perl6", "-pe", "run 'id'"], expected: "perl6 -e" },
|
||||
{ argv: ["ghc", "-e", 'System.Process.system "id"'], expected: "ghc -e" },
|
||||
{ argv: ["ghci", "-e", 'System.Process.system "id"'], expected: "ghci -e" },
|
||||
{ argv: ["erl", "-eval", 'os:cmd("id").'], expected: "erl -eval" },
|
||||
{ argv: ["erl", "-run", "os", "cmd", "id"], expected: "erl -run" },
|
||||
{ argv: ["erl", "-s", "os", "cmd", "id"], expected: "erl -s" },
|
||||
{ argv: ["erl", "-noshell", "-s", "init", "stop"], expected: "erl -s" },
|
||||
{ argv: ["werl", "-eval", 'os:cmd("id").'], expected: "werl -eval" },
|
||||
{ argv: ["werl", "-run", "os", "cmd", "id"], expected: "werl -run" },
|
||||
{ argv: ["gdb", "-ex", "shell id", "-ex", "quit"], expected: "gdb -ex" },
|
||||
{ argv: ["gdb", "-ex=shell id", "-ex", "quit"], expected: "gdb -ex" },
|
||||
{ argv: ["gdb", "-iex", "shell id"], expected: "gdb -iex" },
|
||||
{ argv: ["gdb", "-iex=shell id"], expected: "gdb -iex" },
|
||||
{ argv: ["gdb", "-ev", "shell id"], expected: "gdb -eval-command" },
|
||||
{ argv: ["gdb", "-eval", "shell id"], expected: "gdb -eval-command" },
|
||||
{ argv: ["gdb", "-eval-c", "shell id"], expected: "gdb -eval-command" },
|
||||
{ argv: ["gdb", "-eval-c=shell id"], expected: "gdb -eval-command" },
|
||||
{ argv: ["gdb", "-eval-command", "shell id"], expected: "gdb -eval-command" },
|
||||
{ argv: ["gdb", "-eval-command=shell id"], expected: "gdb -eval-command" },
|
||||
{ argv: ["gdb", "--ev", "shell id"], expected: "gdb --eval-command" },
|
||||
{ argv: ["gdb", "--eval", "shell id"], expected: "gdb --eval-command" },
|
||||
{ argv: ["gdb", "--eval-c=shell id"], expected: "gdb --eval-command" },
|
||||
{ argv: ["gdb", "--eval-command=shell id"], expected: "gdb --eval-command" },
|
||||
{ argv: ["gdb", "-init-e", "shell id"], expected: "gdb -init-eval-command" },
|
||||
{ argv: ["gdb", "-init-eval", "shell id"], expected: "gdb -init-eval-command" },
|
||||
{ argv: ["gdb", "-init-eval-c=shell id"], expected: "gdb -init-eval-command" },
|
||||
{ argv: ["gdb", "--init-e", "shell id"], expected: "gdb --init-eval-command" },
|
||||
{ argv: ["gdb", "--init-eval-command=shell id"], expected: "gdb --init-eval-command" },
|
||||
{ argv: ["gdb", "--init-eval=shell id"], expected: "gdb --init-eval-command" },
|
||||
{ argv: ["gdb", "-init-eval-command=shell id"], expected: "gdb -init-eval-command" },
|
||||
{ argv: ["gdb", "-eiex", "shell id"], expected: "gdb -eiex" },
|
||||
{ argv: ["gdb", "-eiex=shell id"], expected: "gdb -eiex" },
|
||||
{
|
||||
argv: ["gdb", "-early-init-e", "shell id"],
|
||||
expected: "gdb -early-init-eval-command",
|
||||
},
|
||||
{
|
||||
argv: ["gdb", "-early-init-eval", "shell id"],
|
||||
expected: "gdb -early-init-eval-command",
|
||||
},
|
||||
{
|
||||
argv: ["gdb", "--early-init-e=shell id"],
|
||||
expected: "gdb --early-init-eval-command",
|
||||
},
|
||||
{
|
||||
argv: ["gdb", "--early-init-eval=shell id"],
|
||||
expected: "gdb --early-init-eval-command",
|
||||
},
|
||||
{
|
||||
argv: ["gdb", "-early-init-eval-command=shell id"],
|
||||
expected: "gdb -early-init-eval-command",
|
||||
},
|
||||
{ argv: ["expect", "-c", "spawn id"], expected: "expect -c" },
|
||||
{ argv: ["expect", "-cspawn id"], expected: "expect -c" },
|
||||
{ argv: ["lua", "-eprint(1)"], expected: "lua -e" },
|
||||
{ argv: ["osascript", "-e", "beep"], expected: "osascript -e" },
|
||||
{ argv: ["osascript", '-edisplay alert "hi"'], expected: "osascript -e" },
|
||||
@@ -121,6 +257,38 @@ describe("exec inline eval detection", () => {
|
||||
expect(detectInterpreterInlineEvalArgv(["perl", "-0xFFpe", "say 1"])).toBeNull();
|
||||
expect(detectInterpreterInlineEvalArgv(["php", "-F", "filter.php"])).toBeNull();
|
||||
expect(detectInterpreterInlineEvalArgv(["Rscript", "script.R"])).toBeNull();
|
||||
expect(detectInterpreterInlineEvalArgv(["julia", "script.jl"])).toBeNull();
|
||||
expect(detectInterpreterInlineEvalArgv(["elixir", "script.exs"])).toBeNull();
|
||||
expect(detectInterpreterInlineEvalArgv(["elixir", "-eIO.puts(1)"])).toBeNull();
|
||||
expect(detectInterpreterInlineEvalArgv(["iex", "-eIO.puts(1)"])).toBeNull();
|
||||
expect(detectInterpreterInlineEvalArgv(["guile", "script.scm"])).toBeNull();
|
||||
expect(detectInterpreterInlineEvalArgv(["guile", "-c(display 1)"])).toBeNull();
|
||||
expect(detectInterpreterInlineEvalArgv(["guile", "-e(display 1)"])).toBeNull();
|
||||
expect(detectInterpreterInlineEvalArgv(["groovy", "script.groovy"])).toBeNull();
|
||||
expect(
|
||||
detectInterpreterInlineEvalArgv(["groovy", "-encoding", "UTF-8", "script.groovy"]),
|
||||
).toBeNull();
|
||||
expect(
|
||||
detectInterpreterInlineEvalArgv(["groovy", "-encoding=UTF-8", "script.groovy"]),
|
||||
).toBeNull();
|
||||
expect(detectInterpreterInlineEvalArgv(["scala", "script.scala"])).toBeNull();
|
||||
expect(
|
||||
detectInterpreterInlineEvalArgv(["scala", "-encoding", "UTF-8", "script.scala"]),
|
||||
).toBeNull();
|
||||
expect(detectInterpreterInlineEvalArgv(["scala-cli", "script.scala"])).toBeNull();
|
||||
expect(detectInterpreterInlineEvalArgv(["clojure", "-M", "-m", "app.main"])).toBeNull();
|
||||
expect(detectInterpreterInlineEvalArgv(["clojure", "-e(println 1)"])).toBeNull();
|
||||
expect(detectInterpreterInlineEvalArgv(["raku", "script.raku"])).toBeNull();
|
||||
expect(detectInterpreterInlineEvalArgv(["ghc", "Main.hs"])).toBeNull();
|
||||
expect(detectInterpreterInlineEvalArgv(["ghc", "-exclude-module", "Debug.Trace"])).toBeNull();
|
||||
expect(detectInterpreterInlineEvalArgv(["erl", "-sname", "node"])).toBeNull();
|
||||
expect(detectInterpreterInlineEvalArgv(["erl", "-setcookie", "cookie"])).toBeNull();
|
||||
expect(detectInterpreterInlineEvalArgv(["erl", "-shutdown_time", "1000"])).toBeNull();
|
||||
expect(detectInterpreterInlineEvalArgv(["gdb", "-e", "program"])).toBeNull();
|
||||
expect(detectInterpreterInlineEvalArgv(["gdb", "--command=commands.gdb"])).toBeNull();
|
||||
expect(detectInterpreterInlineEvalArgv(["gdb", "-eix", "early.gdb"])).toBeNull();
|
||||
expect(detectInterpreterInlineEvalArgv(["gdb", "-early-init-command", "early.gdb"])).toBeNull();
|
||||
expect(detectInterpreterInlineEvalArgv(["expect", "script.exp"])).toBeNull();
|
||||
expect(detectInterpreterInlineEvalArgv(["r2", "-e", "bin.cache=true", "program"])).toBeNull();
|
||||
expect(detectInterpreterInlineEvalArgv(["awk", "-f", "script.awk", "data.csv"])).toBeNull();
|
||||
expect(detectInterpreterInlineEvalArgv(["find", ".", "-name", "*.ts"])).toBeNull();
|
||||
@@ -142,6 +310,21 @@ describe("exec inline eval detection", () => {
|
||||
expect(isInterpreterLikeAllowlistPattern("pypy3.10")).toBe(true);
|
||||
expect(isInterpreterLikeAllowlistPattern("**/node")).toBe(true);
|
||||
expect(isInterpreterLikeAllowlistPattern("Rscript")).toBe(true);
|
||||
expect(isInterpreterLikeAllowlistPattern("/opt/bin/julia")).toBe(true);
|
||||
expect(isInterpreterLikeAllowlistPattern("**/elixir")).toBe(true);
|
||||
expect(isInterpreterLikeAllowlistPattern("iex")).toBe(true);
|
||||
expect(isInterpreterLikeAllowlistPattern("guile3.0")).toBe(true);
|
||||
expect(isInterpreterLikeAllowlistPattern("/usr/bin/groovy")).toBe(true);
|
||||
expect(isInterpreterLikeAllowlistPattern("scala")).toBe(true);
|
||||
expect(isInterpreterLikeAllowlistPattern("scala-cli")).toBe(true);
|
||||
expect(isInterpreterLikeAllowlistPattern("clojure.exe")).toBe(true);
|
||||
expect(isInterpreterLikeAllowlistPattern("**/clj")).toBe(true);
|
||||
expect(isInterpreterLikeAllowlistPattern("raku")).toBe(true);
|
||||
expect(isInterpreterLikeAllowlistPattern("perl6")).toBe(true);
|
||||
expect(isInterpreterLikeAllowlistPattern("ghci")).toBe(true);
|
||||
expect(isInterpreterLikeAllowlistPattern("erl")).toBe(true);
|
||||
expect(isInterpreterLikeAllowlistPattern("gdb")).toBe(true);
|
||||
expect(isInterpreterLikeAllowlistPattern("expect")).toBe(true);
|
||||
expect(isInterpreterLikeAllowlistPattern("r2")).toBe(false);
|
||||
expect(isInterpreterLikeAllowlistPattern("/usr/bin/awk")).toBe(true);
|
||||
expect(isInterpreterLikeAllowlistPattern("**/gawk")).toBe(true);
|
||||
|
||||
@@ -15,11 +15,22 @@ type PrefixFlagSpec = {
|
||||
prefix: string;
|
||||
};
|
||||
|
||||
type AbbreviatedFlagSpec = {
|
||||
label: string;
|
||||
full: string;
|
||||
min: string;
|
||||
};
|
||||
|
||||
type InterpreterFlagSpec = {
|
||||
names: readonly string[];
|
||||
exactFlags: ReadonlySet<string>;
|
||||
rawExactFlags?: ReadonlyMap<string, string>;
|
||||
rawPrefixFlags?: readonly PrefixFlagSpec[];
|
||||
abbreviatedFlags?: readonly AbbreviatedFlagSpec[];
|
||||
joinedExactFlags?: ReadonlySet<string>;
|
||||
joinedRawExactFlags?: ReadonlyMap<string, string>;
|
||||
joinedFlagDenyExact?: ReadonlySet<string>;
|
||||
joinedFlagDenyPrefixes?: readonly string[];
|
||||
prefixFlags?: readonly PrefixFlagSpec[];
|
||||
shortClusterFlags?: readonly ShortClusterFlagSpec[];
|
||||
scanPastDoubleDash?: boolean;
|
||||
@@ -161,6 +172,107 @@ const FLAG_INTERPRETER_INLINE_EVAL_SPECS: readonly InterpreterFlagSpec[] = [
|
||||
]),
|
||||
},
|
||||
{ names: ["r", "rscript"], exactFlags: new Set(["-e"]) },
|
||||
{
|
||||
names: ["julia"],
|
||||
exactFlags: new Set(["-e", "--eval", "--print"]),
|
||||
rawExactFlags: new Map([["-E", "-E"]]),
|
||||
},
|
||||
{
|
||||
names: ["elixir", "iex"],
|
||||
exactFlags: new Set(["-e", "--eval", "--rpc-eval"]),
|
||||
joinedExactFlags: new Set(),
|
||||
},
|
||||
{ names: ["guile"], exactFlags: new Set(["-c", "-e"]), joinedExactFlags: new Set() },
|
||||
{
|
||||
names: ["groovy"],
|
||||
exactFlags: new Set(["-e"]),
|
||||
joinedFlagDenyExact: new Set(["-encoding"]),
|
||||
joinedFlagDenyPrefixes: ["-encoding="],
|
||||
shortClusterFlags: [
|
||||
{
|
||||
label: "-e",
|
||||
flag: "e",
|
||||
prefixChars: new Set(["n", "p"]),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
names: ["scala", "scala-cli"],
|
||||
exactFlags: new Set([
|
||||
"-e",
|
||||
"--script-snippet",
|
||||
"--execute-script",
|
||||
"--execute-sc",
|
||||
"--execute-scala-script",
|
||||
"--scala-snippet",
|
||||
"--execute-scala",
|
||||
"--java-snippet",
|
||||
"--execute-java",
|
||||
"--markdown-snippet",
|
||||
"--md-snippet",
|
||||
"--execute-markdown",
|
||||
"--execute-md",
|
||||
]),
|
||||
joinedExactFlags: new Set(),
|
||||
},
|
||||
{ names: ["clojure", "clj"], exactFlags: new Set(["-e", "--eval"]), joinedExactFlags: new Set() },
|
||||
{
|
||||
names: ["raku", "perl6"],
|
||||
exactFlags: new Set(["-e"]),
|
||||
joinedExactFlags: new Set(["-e"]),
|
||||
shortClusterFlags: [
|
||||
{
|
||||
label: "-e",
|
||||
flag: "e",
|
||||
prefixChars: new Set(["n", "p"]),
|
||||
},
|
||||
],
|
||||
},
|
||||
{ names: ["ghc", "ghci"], exactFlags: new Set(["-e"]), joinedExactFlags: new Set() },
|
||||
{
|
||||
names: ["erl", "werl"],
|
||||
exactFlags: new Set(["-eval", "-run", "-s"]),
|
||||
joinedExactFlags: new Set(),
|
||||
},
|
||||
{
|
||||
names: ["gdb"],
|
||||
exactFlags: new Set([
|
||||
"-ex",
|
||||
"-iex",
|
||||
"-eiex",
|
||||
"-eval-command",
|
||||
"--eval-command",
|
||||
"-init-eval-command",
|
||||
"--init-eval-command",
|
||||
"-early-init-eval-command",
|
||||
"--early-init-eval-command",
|
||||
]),
|
||||
abbreviatedFlags: [
|
||||
{ label: "-eval-command", full: "-eval-command", min: "-ev" },
|
||||
{ label: "--eval-command", full: "--eval-command", min: "--ev" },
|
||||
{ label: "-init-eval-command", full: "-init-eval-command", min: "-init-e" },
|
||||
{ label: "--init-eval-command", full: "--init-eval-command", min: "--init-e" },
|
||||
{
|
||||
label: "-early-init-eval-command",
|
||||
full: "-early-init-eval-command",
|
||||
min: "-early-init-e",
|
||||
},
|
||||
{
|
||||
label: "--early-init-eval-command",
|
||||
full: "--early-init-eval-command",
|
||||
min: "--early-init-e",
|
||||
},
|
||||
],
|
||||
prefixFlags: [
|
||||
{ label: "-ex", prefix: "-ex=" },
|
||||
{ label: "-iex", prefix: "-iex=" },
|
||||
{ label: "-eiex", prefix: "-eiex=" },
|
||||
{ label: "-eval-command", prefix: "-eval-command=" },
|
||||
{ label: "-init-eval-command", prefix: "-init-eval-command=" },
|
||||
{ label: "-early-init-eval-command", prefix: "-early-init-eval-command=" },
|
||||
],
|
||||
},
|
||||
{ names: ["expect"], exactFlags: new Set(["-c"]) },
|
||||
{ names: ["lua"], exactFlags: new Set(["-e"]) },
|
||||
{ names: ["osascript"], exactFlags: new Set(["-e"]) },
|
||||
{
|
||||
@@ -318,19 +430,40 @@ function createInlineEvalHit(
|
||||
};
|
||||
}
|
||||
|
||||
function matchAbbreviatedFlag(spec: InterpreterFlagSpec, lower: string): string | null {
|
||||
const optionName = lower.split("=", 1)[0] ?? lower;
|
||||
for (const flag of spec.abbreviatedFlags ?? []) {
|
||||
if (
|
||||
optionName.length >= flag.min.length &&
|
||||
flag.full.startsWith(optionName) &&
|
||||
flag.min.startsWith(optionName.slice(0, flag.min.length))
|
||||
) {
|
||||
return flag.label;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function matchJoinedExactFlag(
|
||||
spec: InterpreterFlagSpec,
|
||||
token: string,
|
||||
lower: string,
|
||||
): string | null {
|
||||
if (
|
||||
spec.joinedFlagDenyExact?.has(lower) === true ||
|
||||
spec.joinedFlagDenyPrefixes?.some((prefix) => lower.startsWith(prefix)) === true
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
for (const flag of spec.exactFlags) {
|
||||
if (flag.startsWith("--")) {
|
||||
const prefix = `${flag}=`;
|
||||
if (lower.startsWith(prefix) && lower.length > prefix.length) {
|
||||
return flag;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
for (const flag of spec.joinedExactFlags ?? spec.exactFlags) {
|
||||
if (/^-[A-Za-z]$/.test(flag) && token.startsWith(flag) && token.length > flag.length) {
|
||||
return normalizeLowercaseStringOrEmpty(flag);
|
||||
}
|
||||
@@ -339,7 +472,7 @@ function matchJoinedExactFlag(
|
||||
}
|
||||
|
||||
function matchJoinedRawExactFlag(spec: InterpreterFlagSpec, token: string): string | null {
|
||||
for (const [flag, label] of spec.rawExactFlags ?? []) {
|
||||
for (const [flag, label] of spec.joinedRawExactFlags ?? spec.rawExactFlags ?? []) {
|
||||
if (/^-[A-Za-z]$/.test(flag) && token.startsWith(flag) && token.length > flag.length) {
|
||||
return label;
|
||||
}
|
||||
@@ -424,6 +557,10 @@ export function detectInterpreterInlineEvalArgv(
|
||||
return createInlineEvalHit(executable, argv, rawPrefixFlag.label);
|
||||
}
|
||||
const lower = normalizeLowercaseStringOrEmpty(token);
|
||||
const abbreviatedFlag = matchAbbreviatedFlag(spec, lower);
|
||||
if (abbreviatedFlag) {
|
||||
return createInlineEvalHit(executable, argv, abbreviatedFlag);
|
||||
}
|
||||
if (spec.exactFlags.has(lower)) {
|
||||
return createInlineEvalHit(executable, argv, lower);
|
||||
}
|
||||
|
||||
@@ -1833,6 +1833,193 @@ $0 \\"$1\\"" touch {marker}`,
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it.each([
|
||||
{
|
||||
executable: "julia",
|
||||
first: "julia -e 'println(1)'",
|
||||
second: "julia -e 'run(`id > {marker}`)'",
|
||||
},
|
||||
{
|
||||
executable: "julia",
|
||||
first: "julia '-eprintln(1)'",
|
||||
second: "julia '-Erun(`id > {marker}`)'",
|
||||
},
|
||||
{
|
||||
executable: "elixir",
|
||||
first: "elixir -e 'IO.puts(:ok)'",
|
||||
second: 'elixir -e \'System.cmd("sh", ["-c", "id > {marker}"])\'',
|
||||
},
|
||||
{
|
||||
executable: "elixir",
|
||||
first: "elixir --rpc-eval worker@127.0.0.1 'IO.puts(:ok)'",
|
||||
second: 'elixir --rpc-eval worker@127.0.0.1 \'System.cmd("sh", ["-c", "id > {marker}"])\'',
|
||||
},
|
||||
{
|
||||
executable: "iex",
|
||||
first: "iex -e 'IO.puts(:ok)'",
|
||||
second: 'iex -e \'System.cmd("sh", ["-c", "id > {marker}"])\'',
|
||||
},
|
||||
{
|
||||
executable: "guile",
|
||||
first: "guile -c '(display 1)'",
|
||||
second: "guile -c '(system \"id > {marker}\")'",
|
||||
},
|
||||
{
|
||||
executable: "guile",
|
||||
first: "guile -e main /dev/null",
|
||||
second: "guile -e '(lambda args (system \"id > {marker}\"))' /dev/null",
|
||||
},
|
||||
{
|
||||
executable: "groovy",
|
||||
first: "groovy -e 'println 1'",
|
||||
second: "groovy -e '\"sh -c id > {marker}\".execute()'",
|
||||
},
|
||||
{
|
||||
executable: "groovy",
|
||||
first: "groovy '-eprintln 1'",
|
||||
second: "groovy '-e\"sh -c id > {marker}\".execute()'",
|
||||
},
|
||||
{
|
||||
executable: "groovy",
|
||||
first: "groovy '-encoding:println 1'",
|
||||
second: 'groovy \'-encoding:["sh", "-c", "id > {marker}"].execute()\'',
|
||||
},
|
||||
{
|
||||
executable: "groovy",
|
||||
first: "groovy -ne 'println line'",
|
||||
second: 'groovy -pe \'["sh", "-c", "id > {marker}"].execute()\'',
|
||||
},
|
||||
{
|
||||
executable: "scala",
|
||||
first: "scala -e 'println(1)'",
|
||||
second: "scala -e 'sys.process.Process(\"sh -c id > {marker}\").!'",
|
||||
},
|
||||
{
|
||||
executable: "scala",
|
||||
first: "scala --execute-script 'println(1)'",
|
||||
second: "scala --script-snippet 'sys.process.Process(\"sh -c id > {marker}\").!'",
|
||||
},
|
||||
{
|
||||
executable: "scala-cli",
|
||||
first: "scala-cli --execute-script 'println(1)'",
|
||||
second: "scala-cli --script-snippet 'sys.process.Process(\"sh -c id > {marker}\").!'",
|
||||
},
|
||||
{
|
||||
executable: "clojure",
|
||||
first: "clojure -e '(println 1)'",
|
||||
second: 'clojure -e \'(clojure.java.shell/sh "sh" "-c" "id > {marker}")\'',
|
||||
},
|
||||
{
|
||||
executable: "clj",
|
||||
first: "clj -e '(println 1)'",
|
||||
second: 'clj -e \'(clojure.java.shell/sh "sh" "-c" "id > {marker}")\'',
|
||||
},
|
||||
{
|
||||
executable: "raku",
|
||||
first: "raku -e 'say 1'",
|
||||
second: 'raku -e \'run "sh", "-c", "id > {marker}"\'',
|
||||
},
|
||||
{
|
||||
executable: "raku",
|
||||
first: "raku '-esay 1'",
|
||||
second: 'raku \'-erun "sh", "-c", "id > {marker}"\'',
|
||||
},
|
||||
{
|
||||
executable: "raku",
|
||||
first: "raku -ne 'say $_'",
|
||||
second: 'raku -ne \'run "sh", "-c", "id > {marker}"\'',
|
||||
},
|
||||
{
|
||||
executable: "perl6",
|
||||
first: "perl6 -e 'say 1'",
|
||||
second: 'perl6 -e \'run "sh", "-c", "id > {marker}"\'',
|
||||
},
|
||||
{
|
||||
executable: "perl6",
|
||||
first: "perl6 -pe 'say $_'",
|
||||
second: 'perl6 -pe \'run "sh", "-c", "id > {marker}"\'',
|
||||
},
|
||||
{
|
||||
executable: "ghc",
|
||||
first: "ghc -e '1 + 1'",
|
||||
second: "ghc -e 'System.Process.system \"id > {marker}\"'",
|
||||
},
|
||||
{
|
||||
executable: "ghci",
|
||||
first: "ghci -e '1 + 1'",
|
||||
second: "ghci -e 'System.Process.system \"id > {marker}\"'",
|
||||
},
|
||||
{
|
||||
executable: "erl",
|
||||
first: "erl -eval 'erlang:display(ok).' -noshell -s init stop",
|
||||
second: "erl -eval 'os:cmd(\"id > {marker}\").' -noshell -s init stop",
|
||||
},
|
||||
{
|
||||
executable: "erl",
|
||||
first: "erl -noshell -run init stop",
|
||||
second: "erl -noshell -run os cmd 'id > {marker}' -s init stop",
|
||||
},
|
||||
{
|
||||
executable: "erl",
|
||||
first: "erl -noshell -s init stop",
|
||||
second: "erl -noshell -s os cmd 'id > {marker}' -s init stop",
|
||||
},
|
||||
{
|
||||
executable: "gdb",
|
||||
first: "gdb -ex 'print 1' -ex quit",
|
||||
second: "gdb -ex 'shell id > {marker}' -ex quit",
|
||||
},
|
||||
{
|
||||
executable: "gdb",
|
||||
first: "gdb -iex 'print 1'",
|
||||
second: "gdb -iex 'shell id > {marker}'",
|
||||
},
|
||||
{
|
||||
executable: "gdb",
|
||||
first: "gdb -eval-c 'print 1'",
|
||||
second: "gdb -eval-c 'shell id > {marker}'",
|
||||
},
|
||||
{
|
||||
executable: "gdb",
|
||||
first: "gdb -ev 'print 1'",
|
||||
second: "gdb --ev 'shell id > {marker}'",
|
||||
},
|
||||
{
|
||||
executable: "gdb",
|
||||
first: "gdb -eiex 'print 1'",
|
||||
second: "gdb -early-init-eval 'shell id > {marker}'",
|
||||
},
|
||||
{
|
||||
executable: "expect",
|
||||
first: "expect -c 'puts ok'",
|
||||
second: "expect -c 'exec sh -c \"id > {marker}\"'",
|
||||
},
|
||||
{
|
||||
executable: "expect",
|
||||
first: "expect '-cputs ok'",
|
||||
second: "expect '-cexec sh -c \"id > {marker}\"'",
|
||||
},
|
||||
] as const)(
|
||||
"prevents allow-always bypass for additional inline-eval interpreter: $executable",
|
||||
async ({ executable, first, second }) => {
|
||||
if (process.platform === "win32") {
|
||||
return;
|
||||
}
|
||||
const dir = makeTempDir();
|
||||
makeExecutable(dir, executable);
|
||||
const env = makePathEnv(dir);
|
||||
const marker = path.join(dir, `${executable}-marker`);
|
||||
|
||||
await expectAllowAlwaysBypassBlocked({
|
||||
dir,
|
||||
firstCommand: first,
|
||||
secondCommand: second.replace("{marker}", marker),
|
||||
env,
|
||||
persistedPattern: null,
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
it("prevents allow-always bypass for shell-carried awk interpreters", async () => {
|
||||
if (process.platform === "win32") {
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user