Skip to content

Commit 22e5023

Browse files
committed
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 cea9786 commit 22e5023

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
@@ -9,7 +9,7 @@ const assert = require('node:assert');
99
const fixtures = require('../common/fixtures');
1010
const envSuffix = common.isWindows ? '-windows' : '';
1111

12-
describe('node --run [command]', () => {
12+
describe('node --run [command]', { concurrency: !process.env.TEST_PARALLEL }, () => {
1313
it('returns error on non-existent file', async () => {
1414
const child = await common.spawnPromisified(
1515
process.execPath,
@@ -244,4 +244,19 @@ describe('node --run [command]', () => {
244244
assert.strictEqual(child.stdout, '');
245245
assert.strictEqual(child.code, 1);
246246
});
247+
248+
it('escapes shell characters', async () => {
249+
const child = await common.spawnPromisified(
250+
process.execPath,
251+
[ '--run', `positional-args${envSuffix}`, '--', '%PAYLOAD%', '$PAYLOAD'],
252+
{ cwd: fixtures.path('run-script'), env: { ...process.env, PAYLOAD: 'env value' } },
253+
);
254+
assert.strictEqual(
255+
child.stdout,
256+
common.isWindows ?
257+
`Raw '"^%PAYLOAD^%" "$PAYLOAD"'\r\nArguments: '%PAYLOAD% $PAYLOAD'\r\nThe total number of arguments is: 2\r\n` :
258+
"Arguments: '%PAYLOAD% $PAYLOAD'\nThe total number of arguments is: 2\n");
259+
assert.strictEqual(child.stderr, '');
260+
assert.strictEqual(child.code, 0);
261+
});
247262
});

0 commit comments

Comments
 (0)