Escape special chars in shell scripts

This commit is contained in:
Sander Declerck 2025-10-06 16:25:12 +02:00
parent 04cb001006
commit 486a4b8f68
No known key found for this signature in database
2 changed files with 18 additions and 3 deletions

View file

@ -1,9 +1,15 @@
import { spawnSync, spawn } from "child_process";
function escapeArg(arg) {
// If argument contains spaces or quotes, wrap in double quotes and escape double quotes
if (arg.includes(" ") || arg.includes('"') || arg.includes("'")) {
return '"' + arg.replaceAll('"', '\\"') + '"';
// Shell metacharacters that need escaping
// These characters have special meaning in shells and need to be quoted
const shellMetaChars = /[ "&'|;<>()$`\\!*?[\]{}~#]/;
// If argument contains shell metacharacters, wrap in double quotes
// and escape characters that are special even inside double quotes
if (shellMetaChars.test(arg)) {
// Inside double quotes, we need to escape: " $ ` \
return '"' + arg.replace(/(["`$\\])/g, '\\$1') + '"';
}
return arg;
}

View file

@ -105,5 +105,14 @@ describe("safeSpawn", () => {
assert.strictEqual(spawnCalls[0].command, "npm install axios --save");
assert.strictEqual(spawnCalls[0].options.shell, true);
});
it(`should escape ampersand character (${variant})`, async () => {
await runSafeSpawn(variant, "npx", ["cypress", "run", "--env", "password=foo&bar"]);
assert.strictEqual(spawnCalls.length, 1);
// & should be escaped by wrapping the arg in quotes
assert.strictEqual(spawnCalls[0].command, 'npx cypress run --env "password=foo&bar"');
assert.strictEqual(spawnCalls[0].options.shell, true);
});
}
});