Skip to content

Commit 577d0ea

Browse files
committed
fix: add quoting to git bash arguments when containing special characters on windows
Signed-off-by: Chapman Pendery <[email protected]>
1 parent b044add commit 577d0ea

File tree

1 file changed

+19
-1
lines changed

1 file changed

+19
-1
lines changed

src/runtime/utils.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,28 @@ const getExecutionShell = async (): Promise<undefined | string> => {
2222
}
2323
};
2424

25+
const bashSpecialCharacters = /[&|<>\s]/g;
26+
// escape whitespace & special characters in an argument when not quoted
27+
const shouldEscapeArg = (arg: string) => {
28+
const hasSpecialCharacter = bashSpecialCharacters.test(arg);
29+
const isSingleCharacter = arg.length === 1;
30+
const isQuoted = (arg.startsWith(`"`) && arg.endsWith(`"`)) || (arg.startsWith(`'`) && arg.endsWith(`'`));
31+
return hasSpecialCharacter && !isSingleCharacter && !isQuoted;
32+
};
33+
34+
/* based on libuv process.c used by nodejs, only quotes are escaped for shells. if using git bash need to escape whitespace & special characters in an argument */
35+
const escapeArgs = (shell: string | undefined, args: string[]) => {
36+
// only escape args for git bash
37+
if (process.platform !== "win32" || shell == undefined) return args;
38+
return args.map((arg) => (shouldEscapeArg(arg) ? `"${arg.replaceAll('"', '\\"')}"` : arg));
39+
};
40+
2541
export const buildExecuteShellCommand =
2642
async (timeout: number): Promise<Fig.ExecuteCommandFunction> =>
2743
async ({ command, env, args, cwd }: Fig.ExecuteCommandInput): Promise<Fig.ExecuteCommandOutput> => {
28-
const child = spawn(command, args, { cwd, env: { ...process.env, ...env, ISTERM: "1" }, shell: await getExecutionShell() });
44+
const executionShell = await getExecutionShell();
45+
const escapedArgs = escapeArgs(executionShell, args);
46+
const child = spawn(command, escapedArgs, { cwd, env: { ...process.env, ...env, ISTERM: "1" }, shell: executionShell });
2947
setTimeout(() => child.kill("SIGKILL"), timeout);
3048
let stdout = "";
3149
let stderr = "";

0 commit comments

Comments
 (0)