openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
822 lines (821 loc) • 25.7 kB
JavaScript
import { w as parseStrictPositiveInteger } from "./number-coercion-CLj0HTDM.js";
import { o as normalizeLowercaseStringOrEmpty } from "./string-coerce-CIXf7egm.js";
import { y as uniqueStrings } from "./string-normalization-DsCfAx8q.js";
import { r as splitShellArgs } from "./shell-argv-DE1kujuY.js";
import { A as isEnvAssignmentToken, D as unwrapKnownDispatchWrapperInvocation, M as resolveCarrierCommandArgv, N as normalizeExecutableToken, O as COMMAND_CARRIER_EXECUTABLES, j as parseEnvInvocationPrelude, k as SOURCE_EXECUTABLES, l as isShellWrapperExecutable, m as POSIX_INLINE_COMMAND_FLAGS, o as extractShellWrapperInlineCommand, t as POSIX_PARSEABLE_SHELL_WRAPPERS, x as resolveInlineCommandMatch } from "./shell-wrapper-resolution-CIQIf-gP.js";
import "./exec-wrapper-resolution-eTidWVtU.js";
//#region src/infra/command-analysis/inline-eval.ts
const VERSION_SUFFIX_PATTERN = /-?\d+(?:\.\d+)*$/;
const FLAG_INTERPRETER_INLINE_EVAL_SPECS = [
{
names: [
"python",
"python2",
"python3",
"pypy",
"pypy3"
],
exactFlags: /* @__PURE__ */ new Set(["-c"]),
shortClusterFlags: [{
label: "-c",
flag: "c",
prefixChars: /* @__PURE__ */ new Set([
"B",
"E",
"I",
"O",
"P",
"R",
"S",
"b",
"d",
"i",
"q",
"s",
"u",
"v",
"x"
])
}]
},
{
names: [
"node",
"nodejs",
"bun",
"deno"
],
exactFlags: /* @__PURE__ */ new Set([
"-e",
"--eval",
"-p",
"--print"
])
},
{
names: [
"awk",
"gawk",
"mawk",
"nawk"
],
exactFlags: /* @__PURE__ */ new Set(["-e", "--source"]),
abbreviatedFlags: [{
label: "--source",
full: "--source",
min: "--s"
}],
prefixFlags: [{
label: "--source",
prefix: "--source="
}]
},
{
names: ["ruby"],
exactFlags: /* @__PURE__ */ new Set(["-e"]),
shortClusterFlags: [{
label: "-e",
flag: "e",
prefixChars: /* @__PURE__ */ new Set([
"S",
"U",
"W",
"a",
"c",
"d",
"l",
"n",
"p",
"s",
"v",
"w"
]),
allowNumericRecordSeparator: true,
numericValuePrefixChars: /* @__PURE__ */ new Set(["W"])
}]
},
{
names: ["perl"],
exactFlags: /* @__PURE__ */ new Set(["-e", "-E"]),
shortClusterFlags: [{
label: "-e",
flag: "e",
prefixChars: /* @__PURE__ */ new Set([
"S",
"T",
"W",
"X",
"U",
"V",
"a",
"c",
"d",
"f",
"l",
"n",
"p",
"s",
"t",
"u",
"w"
]),
allowNumericRecordSeparator: true,
numericValuePrefixChars: /* @__PURE__ */ new Set(["l"])
}, {
label: "-e",
flag: "E",
prefixChars: /* @__PURE__ */ new Set([
"S",
"T",
"W",
"X",
"U",
"V",
"a",
"c",
"d",
"f",
"l",
"n",
"p",
"s",
"t",
"u",
"w"
]),
allowNumericRecordSeparator: true,
numericValuePrefixChars: /* @__PURE__ */ new Set(["l"])
}]
},
{
names: ["php"],
exactFlags: /* @__PURE__ */ new Set(["-r"]),
rawExactFlags: /* @__PURE__ */ new Map([
["-B", "-B"],
["-E", "-E"],
["-R", "-R"]
])
},
{
names: ["r", "rscript"],
exactFlags: /* @__PURE__ */ new Set(["-e"])
},
{
names: ["julia"],
exactFlags: /* @__PURE__ */ new Set([
"-e",
"--eval",
"--print"
]),
rawExactFlags: /* @__PURE__ */ new Map([["-E", "-E"]])
},
{
names: ["elixir", "iex"],
exactFlags: /* @__PURE__ */ new Set([
"-e",
"--eval",
"--rpc-eval"
]),
joinedExactFlags: /* @__PURE__ */ new Set()
},
{
names: ["guile"],
exactFlags: /* @__PURE__ */ new Set(["-c", "-e"]),
joinedExactFlags: /* @__PURE__ */ new Set()
},
{
names: ["groovy"],
exactFlags: /* @__PURE__ */ new Set(["-e"]),
joinedFlagDenyExact: /* @__PURE__ */ new Set(["-encoding"]),
joinedFlagDenyPrefixes: ["-encoding="],
shortClusterFlags: [{
label: "-e",
flag: "e",
prefixChars: /* @__PURE__ */ new Set(["n", "p"])
}]
},
{
names: ["scala", "scala-cli"],
exactFlags: /* @__PURE__ */ 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: /* @__PURE__ */ new Set()
},
{
names: ["clojure", "clj"],
exactFlags: /* @__PURE__ */ new Set(["-e", "--eval"]),
joinedExactFlags: /* @__PURE__ */ new Set()
},
{
names: ["raku", "perl6"],
exactFlags: /* @__PURE__ */ new Set(["-e"]),
joinedExactFlags: /* @__PURE__ */ new Set(["-e"]),
shortClusterFlags: [{
label: "-e",
flag: "e",
prefixChars: /* @__PURE__ */ new Set(["n", "p"])
}]
},
{
names: ["ghc", "ghci"],
exactFlags: /* @__PURE__ */ new Set(["-e"]),
joinedExactFlags: /* @__PURE__ */ new Set()
},
{
names: ["erl", "werl"],
exactFlags: /* @__PURE__ */ new Set([
"-eval",
"-run",
"-s"
]),
joinedExactFlags: /* @__PURE__ */ new Set()
},
{
names: ["gdb"],
exactFlags: /* @__PURE__ */ 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: /* @__PURE__ */ new Set(["-c"])
},
{
names: ["lua"],
exactFlags: /* @__PURE__ */ new Set(["-e"])
},
{
names: ["osascript"],
exactFlags: /* @__PURE__ */ new Set(["-e"])
},
{
names: ["find"],
exactFlags: /* @__PURE__ */ new Set([
"-exec",
"-execdir",
"-ok",
"-okdir"
]),
scanPastDoubleDash: true
},
{
names: ["make", "gmake"],
exactFlags: /* @__PURE__ */ new Set([
"-f",
"--file",
"--makefile",
"--eval"
]),
rawExactFlags: /* @__PURE__ */ new Map([["-E", "-E"]]),
rawPrefixFlags: [{
label: "-E",
prefix: "-E"
}],
abbreviatedFlags: [{
label: "--eval",
full: "--eval",
min: "--ev"
}],
prefixFlags: [
{
label: "-f",
prefix: "-f"
},
{
label: "--file",
prefix: "--file="
},
{
label: "--makefile",
prefix: "--makefile="
},
{
label: "--eval",
prefix: "--eval="
}
]
},
{
names: ["sed", "gsed"],
exactFlags: /* @__PURE__ */ new Set(),
rawExactFlags: /* @__PURE__ */ new Map([["-e", "-e"]]),
rawPrefixFlags: [{
label: "-e",
prefix: "-e"
}]
}
];
const POSITIONAL_INTERPRETER_INLINE_EVAL_SPECS = [
{
names: [
"awk",
"gawk",
"mawk",
"nawk"
],
fileFlags: /* @__PURE__ */ new Set(["-f", "--file"]),
fileFlagPrefixes: ["-f", "--file="],
exactValueFlags: /* @__PURE__ */ new Set([
"-f",
"--file",
"-F",
"--field-separator",
"-v",
"--assign",
"-i",
"--include",
"-l",
"--load",
"-W"
]),
prefixValueFlags: [
"-F",
"--field-separator=",
"-v",
"--assign=",
"--include=",
"--load="
],
flag: "<program>"
},
{
names: ["xargs"],
exactValueFlags: /* @__PURE__ */ new Set([
"-a",
"--arg-file",
"-d",
"--delimiter",
"-E",
"-I",
"-L",
"--max-lines",
"-n",
"--max-args",
"-P",
"--max-procs",
"-s",
"--max-chars"
]),
exactOptionalValueFlags: /* @__PURE__ */ new Set(["--eof", "--replace"]),
prefixValueFlags: [
"-a",
"--arg-file=",
"-d",
"--delimiter=",
"-E",
"--eof=",
"-I",
"--replace=",
"-i",
"-L",
"--max-lines=",
"-l",
"-n",
"--max-args=",
"-P",
"--max-procs=",
"-s",
"--max-chars="
],
flag: "<command>"
},
{
names: ["sed", "gsed"],
fileFlags: /* @__PURE__ */ new Set(["-f", "--file"]),
fileFlagPrefixes: ["-f", "--file="],
exactValueFlags: /* @__PURE__ */ new Set([
"-f",
"--file",
"-l",
"--line-length"
]),
exactOptionalValueFlags: /* @__PURE__ */ new Set(["-i", "--in-place"]),
prefixValueFlags: [
"-f",
"--file=",
"--in-place=",
"--line-length="
],
flag: "<program>"
}
];
const INTERPRETER_ALLOWLIST_NAMES = new Set(FLAG_INTERPRETER_INLINE_EVAL_SPECS.flatMap((entry) => entry.names).concat(POSITIONAL_INTERPRETER_INLINE_EVAL_SPECS.flatMap((entry) => entry.names)));
function stripInterpreterVersionSuffix(value) {
const stripped = value.replace(VERSION_SUFFIX_PATTERN, "");
return stripped.length > 0 ? stripped : value;
}
function interpreterNameVariants(value) {
const stripped = stripInterpreterVersionSuffix(value);
return stripped === value || stripped.length < 2 ? [value] : [value, stripped];
}
function specNamesInclude(names, normalizedExecutable) {
return interpreterNameVariants(normalizedExecutable).some((candidate) => names.includes(candidate));
}
function findInterpreterSpec(executable) {
const normalized = normalizeExecutableToken(executable);
for (const spec of FLAG_INTERPRETER_INLINE_EVAL_SPECS) if (specNamesInclude(spec.names, normalized)) return spec;
return null;
}
function findPositionalInterpreterSpec(executable) {
const normalized = normalizeExecutableToken(executable);
for (const spec of POSITIONAL_INTERPRETER_INLINE_EVAL_SPECS) if (specNamesInclude(spec.names, normalized)) return spec;
return null;
}
function createInlineEvalHit(executable, argv, flag) {
return {
executable,
normalizedExecutable: normalizeExecutableToken(executable),
flag,
argv
};
}
function matchAbbreviatedFlag(spec, lower) {
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, token, lower) {
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;
}
for (const flag of spec.joinedExactFlags ?? spec.exactFlags) if (/^-[A-Za-z]$/.test(flag) && token.startsWith(flag) && token.length > flag.length) return normalizeLowercaseStringOrEmpty(flag);
return null;
}
function matchJoinedRawExactFlag(spec, token) {
for (const [flag, label] of spec.joinedRawExactFlags ?? spec.rawExactFlags ?? []) if (/^-[A-Za-z]$/.test(flag) && token.startsWith(flag) && token.length > flag.length) return label;
return null;
}
function matchShortClusterFlag(spec, token) {
if (!token.startsWith("-") || token.startsWith("--")) return null;
for (const clusterFlag of spec.shortClusterFlags ?? []) {
const index = token.indexOf(clusterFlag.flag, 2);
if (index < 2) continue;
if (isShortClusterPrefixAllowed(clusterFlag, token.slice(1, index))) return clusterFlag.label;
}
return null;
}
function isShortClusterPrefixAllowed(clusterFlag, prefix) {
for (let index = 0; index < prefix.length; index += 1) {
const char = prefix[index] ?? "";
if (clusterFlag.prefixChars.has(char)) {
if (clusterFlag.numericValuePrefixChars?.has(char) === true) while (/^[0-9]$/.test(prefix[index + 1] ?? "")) index += 1;
continue;
}
if (clusterFlag.allowNumericRecordSeparator === true && char === "0") {
while (/^[0-9]$/.test(prefix[index + 1] ?? "")) index += 1;
continue;
}
return false;
}
return true;
}
function detectInterpreterInlineEvalArgv(argv) {
if (!Array.isArray(argv) || argv.length === 0) return null;
const executable = argv[0]?.trim();
if (!executable) return null;
const spec = findInterpreterSpec(executable);
if (spec) for (let idx = 1; idx < argv.length; idx += 1) {
const token = argv[idx]?.trim();
if (!token) continue;
if (token === "--") {
if (spec.scanPastDoubleDash) continue;
break;
}
const rawExactFlag = spec.rawExactFlags?.get(token);
if (rawExactFlag) return createInlineEvalHit(executable, argv, rawExactFlag);
const joinedRawExactFlag = matchJoinedRawExactFlag(spec, token);
if (joinedRawExactFlag) return createInlineEvalHit(executable, argv, joinedRawExactFlag);
const rawPrefixFlag = spec.rawPrefixFlags?.find(({ prefix }) => token.startsWith(prefix) && token.length > prefix.length);
if (rawPrefixFlag) 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);
const joinedExactFlag = matchJoinedExactFlag(spec, token, lower);
if (joinedExactFlag) return createInlineEvalHit(executable, argv, joinedExactFlag);
const shortClusterFlag = matchShortClusterFlag(spec, token);
if (shortClusterFlag) return createInlineEvalHit(executable, argv, shortClusterFlag);
const prefixFlag = spec.prefixFlags?.find(({ prefix }) => lower.startsWith(prefix) && lower.length > prefix.length);
if (prefixFlag) return createInlineEvalHit(executable, argv, prefixFlag.label);
}
const positionalSpec = findPositionalInterpreterSpec(executable);
if (!positionalSpec) return null;
for (let idx = 1; idx < argv.length; idx += 1) {
const token = argv[idx]?.trim();
if (!token) continue;
if (token === "--") {
if (!argv[idx + 1]?.trim()) return null;
return createInlineEvalHit(executable, argv, positionalSpec.flag);
}
if (positionalSpec.fileFlags?.has(token)) return null;
if (positionalSpec.fileFlagPrefixes?.some((prefix) => token.startsWith(prefix) && token.length > prefix.length)) return null;
if (positionalSpec.exactValueFlags?.has(token)) {
idx += 1;
continue;
}
if (positionalSpec.exactOptionalValueFlags?.has(token)) continue;
if (positionalSpec.prefixValueFlags?.some((prefix) => token.startsWith(prefix) && token.length > prefix.length)) continue;
if (token.startsWith("-")) continue;
return createInlineEvalHit(executable, argv, positionalSpec.flag);
}
return null;
}
function describeInterpreterInlineEval(hit) {
if (hit.flag === "<command>") return `${hit.normalizedExecutable} inline command`;
if (hit.flag === "<program>") return `${hit.normalizedExecutable} inline program`;
return `${hit.normalizedExecutable} ${hit.flag}`;
}
function isInterpreterLikeAllowlistPattern(pattern) {
const trimmed = normalizeLowercaseStringOrEmpty(pattern);
if (!trimmed) return false;
if (interpreterNameVariants(normalizeExecutableToken(trimmed)).some((candidate) => INTERPRETER_ALLOWLIST_NAMES.has(candidate))) return true;
const basename = trimmed.replace(/\\/g, "/").split("/").pop() ?? trimmed;
return interpreterNameVariants((basename.endsWith(".exe") ? basename.slice(0, -4) : basename).replace(/[*?[\]{}()]/g, "").replace(/[.-]+$/, "")).some((candidate) => INTERPRETER_ALLOWLIST_NAMES.has(candidate));
}
//#endregion
//#region src/infra/command-analysis/risks.ts
function commandArgvKey(argv) {
return argv.join("\0");
}
function isCommandCarrierExecutable(executable, options) {
return COMMAND_CARRIER_EXECUTABLES.has(executable) || Boolean(options?.includeExec && executable === "exec");
}
/** Builds candidate command argv arrays from nested carriers and shell wrappers. */
function buildCommandPayloadArgvCandidates(argv, seenArgv = /* @__PURE__ */ new Set()) {
const key = commandArgvKey(argv);
if (seenArgv.has(key)) return argv.length > 0 ? [argv] : [];
seenArgv.add(key);
const assignmentStrippedArgv = stripLeadingEnvAssignments(argv);
const carriedArgv = resolveCarrierCommandArgv(assignmentStrippedArgv, 0, { includeExec: true });
const executableArgv = carriedArgv ?? assignmentStrippedArgv;
const carriedCandidates = carriedArgv ? buildCommandPayloadArgvCandidates(carriedArgv, seenArgv) : [];
const shellWrapperPayload = extractShellWrapperInlineCommand(executableArgv);
const shellWrapperCandidates = shellWrapperPayload ? (() => {
const innerArgv = splitShellArgs(shellWrapperPayload);
return innerArgv ? buildCommandPayloadArgvCandidates(innerArgv, seenArgv) : [[shellWrapperPayload]];
})() : [];
return uniqueCommandPayloadArgvCandidates([
...executableArgv.length > 0 ? [executableArgv] : [],
...carriedCandidates,
...shellWrapperCandidates
]);
}
/** Builds candidate command payload strings from nested carriers and shell wrappers. */
function buildCommandPayloadCandidates(argv, seenArgv = /* @__PURE__ */ new Set()) {
return uniqueStrings(buildCommandPayloadArgvCandidates(argv, seenArgv).map((candidate) => candidate.join(" ")));
}
function stripLeadingEnvAssignments(argv) {
let index = 0;
while (index < argv.length && isEnvAssignmentToken(argv[index] ?? "")) index += 1;
return index > 0 ? argv.slice(index) : argv;
}
function uniqueCommandPayloadArgvCandidates(candidates) {
const seen = /* @__PURE__ */ new Set();
return candidates.filter((candidate) => {
if (candidate.length === 0) return false;
const key = commandArgvKey(candidate);
if (seen.has(key)) return false;
seen.add(key);
return true;
});
}
function normalizeShellPositionalToken(token) {
const match = (token.length >= 2 && token.startsWith("\"") && token.endsWith("\"") ? token.slice(1, -1) : token).match(/^\$(?:([0-9@*])|\{([0-9@*])\})$/u);
const value = match?.[1] ?? match?.[2];
if (value === void 0) return null;
if (value === "@") return { kind: "all" };
if (value === "*") return { kind: "star" };
if (value === "0") return { kind: "zero" };
const index = parseStrictPositiveInteger(value);
return index === void 0 ? null : {
kind: "index",
index
};
}
function resolveShellPositionalCarrierPlan(command) {
const trimmed = command.trim();
if (trimmed.length === 0) return null;
const shellWhitespace = String.raw`[^\S\r\n]+`;
const positionalZero = String.raw`(?:\$(?:0|\{0\})|"\$(?:0|\{0\})")`;
const positionalArg = String.raw`(?:\$(?:[@*]|[1-9]|\{[@*1-9]\})|"\$(?:[@*]|[1-9]|\{[@*1-9]\})")`;
if (!new RegExp(`^(?:exec${shellWhitespace}(?:--${shellWhitespace})?)?${positionalZero}(?:${shellWhitespace}${positionalArg})*$`, "u").test(trimmed)) return null;
const tokens = trimmed.match(/"[^"]*"|\S+/gu) ?? [];
let index = 0;
if (tokens[index] === "exec") {
index += 1;
if (tokens[index] === "--") index += 1;
}
if (normalizeShellPositionalToken(tokens[index] ?? "")?.kind !== "zero") return null;
index += 1;
const indexes = [0];
for (; index < tokens.length; index += 1) {
const positional = normalizeShellPositionalToken(tokens[index] ?? "");
if (positional === null || positional.kind === "zero" || positional.kind === "star") return null;
if (positional.kind === "all") return { kind: "all" };
if (positional.kind === "index") indexes.push(positional.index);
}
return {
kind: "indexes",
indexes
};
}
function resolveShellPositionalCarrierArgv(params) {
const positionalArgv = params.executableArgv.slice(params.valueTokenIndex + 1);
return (params.plan.kind === "all" ? positionalArgv : params.plan.indexes.map((index) => positionalArgv[index] ?? "")).map((token) => token.trim()).filter((token) => token.length > 0);
}
function detectShellPositionalCarrierInlineEvalArgvInternal(argv, seenArgv) {
const executableArgv = stripLeadingEnvAssignments(argv);
const executable = normalizeExecutableToken(executableArgv[0] ?? "");
if (!isShellWrapperExecutable(executable)) return null;
if (!POSIX_PARSEABLE_SHELL_WRAPPERS.has(executable)) return null;
const key = commandArgvKey(executableArgv);
if (seenArgv.has(key)) return null;
seenArgv.add(key);
const inlineMatch = resolveInlineCommandMatch(executableArgv, POSIX_INLINE_COMMAND_FLAGS, { allowCombinedC: true });
if (inlineMatch.valueTokenIndex === null || !inlineMatch.command) return null;
const carrierPlan = resolveShellPositionalCarrierPlan(inlineMatch.command);
if (!carrierPlan) return null;
const carriedArgv = resolveShellPositionalCarrierArgv({
executableArgv,
valueTokenIndex: inlineMatch.valueTokenIndex,
plan: carrierPlan
});
if (carriedArgv.length === 0) return null;
return detectInlineEvalArgvInternal(carriedArgv, seenArgv);
}
function detectCarrierInlineEvalArgvInternal(argv, seenArgv) {
const executableArgv = stripLeadingEnvAssignments(argv);
const key = commandArgvKey(executableArgv);
if (seenArgv.has(key)) return null;
seenArgv.add(key);
const dispatchUnwrap = unwrapKnownDispatchWrapperInvocation(executableArgv);
if (dispatchUnwrap.kind === "unwrapped") return detectInlineEvalArgvInternal(dispatchUnwrap.argv, seenArgv);
if (!isCommandCarrierExecutable(normalizeExecutableToken(executableArgv[0] ?? ""), { includeExec: true })) return null;
const carriedArgv = resolveCarrierCommandArgv(executableArgv, 0, { includeExec: true });
if (!carriedArgv) return null;
return detectInlineEvalArgvInternal(carriedArgv, seenArgv);
}
function detectCarrierInlineEvalArgv(argv) {
return detectCarrierInlineEvalArgvInternal(argv, /* @__PURE__ */ new Set());
}
function detectInlineEvalArgvInternal(argv, seenArgv) {
if (!Array.isArray(argv)) return null;
return detectInterpreterInlineEvalArgv(argv) ?? detectShellPositionalCarrierInlineEvalArgvInternal(argv, seenArgv) ?? detectCarrierInlineEvalArgvInternal(argv, seenArgv);
}
function detectInlineEvalArgv(argv) {
return detectInlineEvalArgvInternal(argv, /* @__PURE__ */ new Set());
}
function detectInlineEvalInSegments(segments) {
for (const segment of segments) {
const hit = detectInlineEvalArgv(segment.resolution?.effectiveArgv ?? segment.argv) ?? detectInlineEvalArgv(segment.argv);
if (hit) return hit;
}
return null;
}
function detectCommandCarrierArgv(argv) {
const executable = argv[0];
if (!executable) return [];
const normalizedExecutable = normalizeExecutableToken(executable);
const hits = [];
if (normalizedExecutable === "find") {
const flag = argv.find((arg) => [
"-exec",
"-execdir",
"-ok",
"-okdir"
].includes(arg));
if (flag) hits.push({
command: executable,
flag
});
}
if (normalizedExecutable === "xargs") hits.push({ command: normalizedExecutable });
if (unwrapKnownDispatchWrapperInvocation(argv).kind === "blocked") hits.push({ command: normalizedExecutable });
const splitStringFlag = detectEnvSplitStringFlag(argv);
if (splitStringFlag) hits.push({
command: normalizedExecutable,
flag: splitStringFlag
});
return hits;
}
function detectEnvSplitStringFlag(argv) {
if (normalizeExecutableToken(argv[0] ?? "") !== "env") return null;
const parsed = parseEnvInvocationPrelude(argv);
if (!parsed?.splitArgv) return null;
for (const arg of argv.slice(1, parsed.commandIndex)) {
const token = arg.trim();
if (token === "-S" || token === "-s") return token;
if (token === "--split-string") return "--split-string";
if (token.startsWith("--split-string=") || token.startsWith("-S") && token.length > 2) return token.startsWith("--") ? "--split-string" : "-S";
if (token.startsWith("-") && !token.startsWith("--")) for (const option of token.slice(1)) {
if (option === "S") return "-S";
if (option === "s") return "-s";
}
}
return null;
}
function detectShellWrapperThroughCarrierArgv(argv, shellCommandFlag) {
const executable = normalizeExecutableToken(argv[0] ?? "");
if (!isCommandCarrierExecutable(executable, { includeExec: true })) return null;
const carriedArgv = resolveCarrierCommandArgv(argv, 0, { includeExec: true });
if (!carriedArgv) return null;
if (isShellWrapperExecutable(carriedArgv[0] ?? "") && shellCommandFlag(carriedArgv, 1)) return executable;
return detectShellWrapperThroughCarrierArgv(carriedArgv, shellCommandFlag) ? executable : null;
}
function detectCarriedShellBuiltinArgv(argv) {
if (!isCommandCarrierExecutable(normalizeExecutableToken(argv[0] ?? ""), { includeExec: true })) return null;
const carriedArgv = resolveCarrierCommandArgv(argv, 0, { includeExec: true });
if (!carriedArgv) return null;
const nestedCarrierHit = detectCarriedShellBuiltinArgv(carriedArgv);
if (nestedCarrierHit) return nestedCarrierHit;
const carriedCommand = carriedArgv[0];
const normalizedCarriedCommand = carriedCommand ? normalizeExecutableToken(carriedCommand) : void 0;
if (normalizedCarriedCommand === "eval") return { kind: "eval" };
if (normalizedCarriedCommand && SOURCE_EXECUTABLES.has(normalizedCarriedCommand)) return {
kind: "source",
command: normalizedCarriedCommand
};
return null;
}
//#endregion
export { detectCommandCarrierArgv as a, detectShellWrapperThroughCarrierArgv as c, detectCarrierInlineEvalArgv as i, describeInterpreterInlineEval as l, buildCommandPayloadCandidates as n, detectInlineEvalArgv as o, detectCarriedShellBuiltinArgv as r, detectInlineEvalInSegments as s, buildCommandPayloadArgvCandidates as t, isInterpreterLikeAllowlistPattern as u };