MCPcopy Create free account
hub / github.com/sindresorhus/execa / escapeWindowsCommand

Function escapeWindowsCommand

lib/arguments/command-file.js:28–63  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

26const batchFileRegExp = /\.(?:bat|cmd)$/i;
27
28const escapeWindowsCommand = parsed => {
29 // Resolve the file to an absolute path, following its shebang to the interpreter if any
30 const resolvedFile = resolveWithShebang(parsed);
31
32 // A directly executable file is spawned by its resolved path, bypassing `cmd.exe` and its escaping
33 if (resolvedFile !== undefined && directlyExecutableRegExp.test(resolvedFile)) {
34 if (parsed.options.argv0 === undefined) {
35 parsed.options.argv0 = parsed.file;
36 }
37
38 parsed.file = resolvedFile;
39 return parsed;
40 }
41
42 /*
43 `cmd.exe` treats CR and LF as command separators and offers no way to escape them, so allowing either would enable command injection.
44 Reject them instead.
45 */
46 for (const value of [parsed.file, ...parsed.commandArguments]) {
47 assertNoLineBreak(value);
48 }
49
50 const isDoubleEscape = resolvedFile !== undefined && batchFileRegExp.test(resolvedFile);
51 // POSIX separators must become Windows ones (`foo/bar` -> `foo\bar`), otherwise resolution always fails with ENOENT
52 const escapedFile = escapeMetaChars(path.normalize(resolvedFile ?? parsed.file));
53 const escapedArguments = parsed.commandArguments.map(argument => escapeArgument(argument, isDoubleEscape));
54 const commandLine = `"${[escapedFile, ...escapedArguments].join(' ')}"`;
55
56 // Let `node:child_process` pass the already-escaped command line through untouched
57 parsed.options.windowsVerbatimArguments = true;
58 return {
59 file: process.env.comspec || 'cmd.exe',
60 commandArguments: ['/d', '/s', '/c', commandLine],
61 options: parsed.options,
62 };
63};
64
65// Resolve the command's absolute path, then, if it is a shebang script, resolve its interpreter instead, since Windows cannot run shebangs natively
66const resolveWithShebang = parsed => {

Callers 1

parseCommandFileFunction · 0.85

Calls 4

resolveWithShebangFunction · 0.85
assertNoLineBreakFunction · 0.85
escapeMetaCharsFunction · 0.85
escapeArgumentFunction · 0.85

Tested by

no test coverage detected