Files
OmniRoute/tests/unit/cli/_helpers/shellArgs.mjs
Paco Cartones e0a22ff619 test(cli): make the CLI suite pass on Windows (#11240)
Validated on the combined 12-PR batch board: the touched CLI test files pass (alias-resolver-7791, run-command — incl. the new shellArgs helper), typecheck:core clean. Test-side only, no production behavior change. Thank you @pacocartones!
2026-08-23 14:24:15 -03:00

42 lines
1.6 KiB
JavaScript

/**
* Reverse the Windows `shell: true` argument escaping so assertions can be
* written against the logical argv on every platform.
*
* `bin/cli/commands/run.mjs` escapes argv before spawning, because on win32 the
* launchers must go through cmd.exe to run npm `.cmd` shims (CVE-2024-27980)
* and Node's `shell: true` joins argv with no escaping at all (DEP0190). That
* escaping is correct and deliberate, but it means `plan.args` holds
* `^^^"--model^^^"` on Windows where it holds `--model` elsewhere.
*
* Tests care about *which* arguments a plan carries, not about how they survive
* cmd.exe, so they normalise first. Keep this in sync with
* `escapeWindowsShellArg` in bin/cli/utils/winShellArgs.mjs.
*/
/**
* @param {unknown} arg
* @returns {string}
*/
export function unescapeWindowsShellArg(arg) {
let s = String(arg);
// 1. undo the two caret passes applied to cmd.exe metacharacters
s = s.replace(/\^(.)/g, "$1").replace(/\^(.)/g, "$1");
// 2. drop the wrapping quotes added by the CRT argv layer
if (s.length >= 2 && s.startsWith('"') && s.endsWith('"')) s = s.slice(1, -1);
// 3. undo the doubled backslashes and the escaped embedded quotes
s = s.replace(/\\\\/g, "\\").replace(/\\"/g, '"');
return s;
}
/**
* Normalise a plan's argv to its logical form. A no-op off Windows.
*
* @param {unknown[]} args
* @param {NodeJS.Platform|string} [platform]
* @returns {string[]}
*/
export function logicalArgs(args, platform = process.platform) {
const list = [...(args ?? [])].map(String);
return platform === "win32" ? list.map(unescapeWindowsShellArg) : list;
}