Skip to content

Commit 73eed9b

Browse files
authored
src: escape Windows environment variables in task runner
Signed-off-by: Antoine du Hamel <duhamelantoine1995@gmail.com> PR-URL: #65217 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: Tierney Cyren <hello@bnb.im>
1 parent c3d68ef commit 73eed9b

2 files changed

Lines changed: 18 additions & 2 deletions

File tree

src/node_task_runner.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ std::string EscapeShell(const std::string_view input) {
154154
}
155155

156156
static constexpr std::string_view forbidden_characters =
157-
"[\t\n\r \"#$&'()*;<>?\\\\`|~]";
157+
"[\t\n\r \"#$&'()*;<>%?\\\\`|~]";
158158

159159
// Check if input contains any forbidden characters
160160
// If it doesn't, return the input as is.
@@ -174,6 +174,7 @@ std::string EscapeShell(const std::string_view input) {
174174
static const std::regex tripleSingleQuote("\\\\\"\"\"");
175175
escaped = std::regex_replace(escaped, leadingQuotePairs, "");
176176
escaped = std::regex_replace(escaped, tripleSingleQuote, "\\\"");
177+
escaped = std::regex_replace(escaped, std::regex("%"), "^%");
177178
#else
178179
// Replace single quotes("'") with `'"'"'` and wrap the result
179180
// in single quotes.

test/parallel/test-node-run.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ const fixtures = require('../common/fixtures');
1212
const tmpdir = require('../common/tmpdir');
1313
const envSuffix = common.isWindows ? '-windows' : '';
1414

15-
describe('node --run [command]', () => {
15+
describe('node --run [command]', { concurrency: !process.env.TEST_PARALLEL }, () => {
1616
it('returns error on non-existent file', async () => {
1717
const child = await common.spawnPromisified(
1818
process.execPath,
@@ -286,4 +286,19 @@ describe('node --run [command]', () => {
286286
assert.strictEqual(child.stdout, '');
287287
assert.strictEqual(child.code, 1);
288288
});
289+
290+
it('escapes shell characters', async () => {
291+
const child = await common.spawnPromisified(
292+
process.execPath,
293+
[ '--run', `positional-args${envSuffix}`, '--', '%PAYLOAD%', '$PAYLOAD'],
294+
{ cwd: fixtures.path('run-script'), env: { ...process.env, PAYLOAD: 'env value' } },
295+
);
296+
assert.strictEqual(
297+
child.stdout,
298+
common.isWindows ?
299+
`Raw '"^%PAYLOAD^%" "$PAYLOAD"'\r\nArguments: '%PAYLOAD% $PAYLOAD'\r\nThe total number of arguments is: 2\r\n` :
300+
"Arguments: '%PAYLOAD% $PAYLOAD'\nThe total number of arguments is: 2\n");
301+
assert.strictEqual(child.stderr, '');
302+
assert.strictEqual(child.code, 0);
303+
});
289304
});

0 commit comments

Comments
 (0)