fix(exec): keep strict inline-eval interpreter approvals reusable

This commit is contained in:
luoyanglang
2026-04-03 00:06:08 +08:00
committed by Peter Steinberger
parent a941a4fef9
commit 7c83cae425
2 changed files with 32 additions and 1 deletions

View File

@@ -1,6 +1,7 @@
import fs from "node:fs";
import path from "node:path";
import { describe, expect, it } from "vitest";
import { resolveAllowAlwaysPatternEntries } from "./exec-approvals-allowlist.js";
import {
makeMockCommandResolution,
makeMockExecutableResolution,
@@ -268,6 +269,29 @@ describe("resolveAllowAlwaysPatterns", () => {
expect(persisted).toEqual([]);
});
it("persists benign awk interpreters without argv binding in strict inline-eval mode on Windows", () => {
const awk = "C:\\temp\\awk.exe";
const entries = resolveAllowAlwaysPatternEntries({
segments: [
{
raw: `${awk} -F , -f script.awk data.csv`,
argv: [awk, "-F", ",", "-f", "script.awk", "data.csv"],
resolution: makeMockCommandResolution({
execution: makeMockExecutableResolution({
rawExecutable: awk,
resolvedPath: awk,
executableName: "awk",
}),
}),
},
],
platform: "win32",
strictInlineEval: true,
});
expect(entries).toEqual([{ pattern: awk }]);
});
it("unwraps shell wrappers and persists the inner executable instead", () => {
if (process.platform === "win32") {
return;

View File

@@ -958,7 +958,14 @@ function collectAllowAlwaysPatterns(params: {
}
}
if (!trustPlan.shellWrapperExecutable) {
const argPattern = buildArgPatternFromArgv(segment.argv, params.platform);
// In strict inline-eval mode we deliberately persist benign interpreter
// executables without an argv binding so later inline-eval attempts match
// the binary and get rejected by strictInlineEval instead of reopening the
// generic allowlist approval prompt on Windows.
const argPattern =
params.strictInlineEval === true && isInterpreterLikeAllowlistPattern(candidatePath)
? undefined
: buildArgPatternFromArgv(segment.argv, params.platform);
addAllowAlwaysPattern(params.out, candidatePath, argPattern);
return;
}