Skip to content

Commit 90a7bc5

Browse files
committed
Fixes moxystudio#51: can spawn commands containing %<environment variable name>%
Passes command string to cmd.exe as an environment variable cmd.exe unsets the environment variable and then runs the command cross-spawn avoids environment variable naming conflicts
1 parent c72b170 commit 90a7bc5

File tree

1 file changed

+26
-3
lines changed

1 file changed

+26
-3
lines changed

lib/parse.js

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ function parseNonShell(parsed) {
1414
var shebang;
1515
var needsShell;
1616
var applyQuotes;
17+
var command;
18+
var args;
19+
var envVariableName;
20+
var envVariableSuffix = 1;
1721

1822
if (!isWin) {
1923
return parsed;
@@ -36,13 +40,20 @@ function parseNonShell(parsed) {
3640
if (needsShell) {
3741
// Escape command & arguments
3842
applyQuotes = (parsed.command !== 'echo'); // Do not quote arguments for the special "echo" command
39-
parsed.command = escapeCommand(parsed.command);
40-
parsed.args = parsed.args.map(function (arg) {
43+
command = escapeCommand(parsed.command);
44+
args = parsed.args.map(function (arg) {
4145
return escapeArgument(arg, applyQuotes);
4246
});
4347

4448
// Make use of cmd.exe
45-
parsed.args = ['/d', '/s', '/c', '"' + parsed.command + (parsed.args.length ? ' ' + parsed.args.join(' ') : '') + '"'];
49+
// Pass command as environment variable
50+
parsed.options.env = assign({}, parsed.options.env || process.env);
51+
do {
52+
envVariableName = 'cross_spawn_command_' + envVariableSuffix;
53+
envVariableSuffix += 1;
54+
} while (Object.prototype.hasOwnProperty.call(parsed.options.env, envVariableName));
55+
parsed.options.env[envVariableName] = command + (args.length ? ' ' + args.join(' ') : '');
56+
parsed.args = ['/d', '/s', '/c', '"set ' + envVariableName + '=& %' + envVariableName + '%"'];
4657
parsed.command = process.env.comspec || 'cmd.exe';
4758
parsed.options.windowsVerbatimArguments = true; // Tell node's spawn that the arguments are already escaped
4859
}
@@ -107,4 +118,16 @@ function parse(command, args, options) {
107118
return options.shell ? parseShell(parsed) : parseNonShell(parsed);
108119
}
109120

121+
// Like Object.assign, for older node versions
122+
function assign(target, source) {
123+
var key;
124+
125+
for (key in source) {
126+
if (Object.prototype.hasOwnProperty.call(source, key)) {
127+
target[key] = source[key];
128+
}
129+
}
130+
return target;
131+
}
132+
110133
module.exports = parse;

0 commit comments

Comments
 (0)