mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-14 11:30:41 +00:00
75 lines
1.4 KiB
TypeScript
75 lines
1.4 KiB
TypeScript
const DOUBLE_QUOTE_ESCAPES = new Set(["\\", '"', "$", "`", "\n", "\r"]);
|
|
|
|
function isDoubleQuoteEscape(next: string | undefined): next is string {
|
|
return Boolean(next && DOUBLE_QUOTE_ESCAPES.has(next));
|
|
}
|
|
|
|
export function splitShellArgs(raw: string): string[] | null {
|
|
const tokens: string[] = [];
|
|
let buf = "";
|
|
let inSingle = false;
|
|
let inDouble = false;
|
|
let escaped = false;
|
|
|
|
const pushToken = () => {
|
|
if (buf.length > 0) {
|
|
tokens.push(buf);
|
|
buf = "";
|
|
}
|
|
};
|
|
|
|
for (let i = 0; i < raw.length; i += 1) {
|
|
const ch = raw[i];
|
|
if (escaped) {
|
|
buf += ch;
|
|
escaped = false;
|
|
continue;
|
|
}
|
|
if (!inSingle && !inDouble && ch === "\\") {
|
|
escaped = true;
|
|
continue;
|
|
}
|
|
if (inSingle) {
|
|
if (ch === "'") {
|
|
inSingle = false;
|
|
} else {
|
|
buf += ch;
|
|
}
|
|
continue;
|
|
}
|
|
if (inDouble) {
|
|
const next = raw[i + 1];
|
|
if (ch === "\\" && isDoubleQuoteEscape(next)) {
|
|
buf += next;
|
|
i += 1;
|
|
continue;
|
|
}
|
|
if (ch === '"') {
|
|
inDouble = false;
|
|
} else {
|
|
buf += ch;
|
|
}
|
|
continue;
|
|
}
|
|
if (ch === "'") {
|
|
inSingle = true;
|
|
continue;
|
|
}
|
|
if (ch === '"') {
|
|
inDouble = true;
|
|
continue;
|
|
}
|
|
if (/\s/.test(ch)) {
|
|
pushToken();
|
|
continue;
|
|
}
|
|
buf += ch;
|
|
}
|
|
|
|
if (escaped || inSingle || inDouble) {
|
|
return null;
|
|
}
|
|
pushToken();
|
|
return tokens;
|
|
}
|