/** * @fileoverview Build `spawn()` arguments that are safe on Windows without `shell: true`. * * With `shell: true`, Node joins the arguments into one command line WITHOUT escaping, * so cmd.exe interprets `&`, `|`, `>`, `^`, `%` and quotes inside arguments. Dropping the * shell is not enough either: since the CVE-2024-27980 fix, Node refuses to spawn * `.cmd`/`.bat` files (e.g. `npm.cmd`, `pnpm.cmd`) without one (EINVAL). * * So on Windows we resolve the command ourselves. An `.exe`/`.com` is spawned directly. * Anything else (a batch file, or a command we could not resolve) runs through * `cmd.exe /d /s /c ""` with every part of `` escaped for cmd.exe, and * `windowsVerbatimArguments` so Node does not quote it a second time. * * Adapted from cross-spawn (https://github.com/moxystudio/node-cross-spawn, * lib/parse.js and lib/util/escape.js), MIT License, * Copyright (c) 2018 Made With MOXY Lda . * The argument quoting follows https://qntm.org/cmd. Differences from cross-spawn 7.0.6: * - Backslashes are handled by a linear scan. cross-spawn's backtracking-safe regex keeps * only one extra backslash for a run of two or more before a quote or the end of the * argument, so `a\\"b` loses a backslash and `a\\` escapes the closing quote. * - Arguments are double-escaped for every `.cmd`/`.bat` target, not only * `node_modules/.bin` shims: global shims such as `npm.cmd` also re-parse `%*`, and a * single-escaped `"` inside an argument would end the quoting there. * - Arguments containing CR or LF are rejected on the cmd.exe path, since cmd.exe * cannot pass them through (a line feed ends the command). * - No shebang detection. */ /** Options for {@link prepareSpawn}. */ export interface PrepareSpawnOptions { /** Target platform (default: `process.platform`). */ platform?: NodeJS.Platform; /** Environment the child will receive; used for PATH, PATHEXT and ComSpec (default: `process.env`). */ env?: NodeJS.ProcessEnv; /** Working directory the child will run in; used to resolve the command (default: `process.cwd()`). */ cwd?: string; /** File-existence probe used to resolve the command (default: `fs.statSync(path).isFile()`). */ isFile?: (path: string) => boolean; } /** The command, arguments and verbatim flag to pass to `spawn()` with `shell: false`. */ export interface PreparedSpawn { command: string; args: string[]; /** True when `args` are already escaped for cmd.exe; pass it to `spawn()`. */ windowsVerbatimArguments: boolean; } /** * Escape a command name for cmd.exe by caret-escaping its metacharacters. */ export declare function escapeCommand(command: string): string; /** * Quote an argument for the MSVCRT / CommandLineToArgvW parser, then caret-escape it * for cmd.exe. * * @param doubleEscapeMetaChars - Escape the cmd.exe metacharacters twice, for batch files * whose arguments cmd.exe parses a second time. */ export declare function escapeArgument(arg: string, doubleEscapeMetaChars?: boolean): string; /** * Resolve a command to a file the way cmd.exe does: the working directory first, then each * PATH entry, trying the PATHEXT extensions unless the command already has one. * * @returns The absolute Windows path, or undefined when nothing matches */ export declare function resolveWindowsCommand(command: string, options: { env: NodeJS.ProcessEnv; cwd: string; isFile?: (path: string) => boolean; }): string | undefined; /** * Prepare a command for `spawn(command, args, { shell: false, windowsVerbatimArguments })` * so that no argument is interpreted by a shell. * * - Not Windows: returned unchanged. * - Windows, resolves to `.exe`/`.com`: the resolved path, spawned directly. * - Windows, resolves to `.cmd`/`.bat` or not resolved: `cmd.exe /d /s /c ""` with the * command and every argument escaped for cmd.exe (twice for batch files). * * @throws Error if an argument that must go through cmd.exe contains CR or LF */ export declare function prepareSpawn(command: string, args: readonly string[], options?: PrepareSpawnOptions): PreparedSpawn; //# sourceMappingURL=windows-spawn.d.ts.map