diff --git a/src/node_task_runner.cc b/src/node_task_runner.cc index 3e15a70e72660c..22c02e83e12ed6 100644 --- a/src/node_task_runner.cc +++ b/src/node_task_runner.cc @@ -171,10 +171,10 @@ std::string EscapeShell(const std::string_view input) { escaped = std::regex_replace(escaped, leadingQuotePairs, ""); escaped = std::regex_replace(escaped, tripleSingleQuote, "\\\""); #else - // Replace single quotes("'") with "\\'" and wrap the result + // Replace single quotes("'") with `'"'"'` and wrap the result // in single quotes. std::string escaped = - std::regex_replace(std::string(input), std::regex("'"), "\\'"); + std::regex_replace(std::string(input), std::regex("'"), "'\"'\"'"); escaped = "'" + escaped + "'"; // Remove excessive quote pairs and handle edge cases static const std::regex tripleSingleQuote("\\\\'''"); diff --git a/test/cctest/test_node_task_runner.cc b/test/cctest/test_node_task_runner.cc index a2c520d2709f2e..1c715124bd88ee 100644 --- a/test/cctest/test_node_task_runner.cc +++ b/test/cctest/test_node_task_runner.cc @@ -28,12 +28,12 @@ TEST_F(TaskRunnerTest, EscapeShell) { {"test words", "'test words'"}, {"$1", "'$1'"}, {"\"$1\"", "'\"$1\"'"}, - {"'$1'", "'\\'$1\\''"}, + {"'$1'", "\"'\"'$1'\"'\"''"}, {"\\$1", "'\\$1'"}, {"--arg=\"$1\"", "'--arg=\"$1\"'"}, {"--arg=node exec -c \"$1\"", "'--arg=node exec -c \"$1\"'"}, - {"--arg=node exec -c '$1'", "'--arg=node exec -c \\'$1\\''"}, - {"'--arg=node exec -c \"$1\"'", "'\\'--arg=node exec -c \"$1\"\\''"} + {"--arg=node exec -c '$1'", "'--arg=node exec -c '\"'\"'$1'\"'\"''"}, + {"'--arg=node exec -c \"$1\"'", "\"'\"'--arg=node exec -c \"$1\"'\"'\"''"} #endif }; diff --git a/test/fixtures/run-script/package.json b/test/fixtures/run-script/package.json index 138f47f2f97408..1a6b66475ca5cf 100644 --- a/test/fixtures/run-script/package.json +++ b/test/fixtures/run-script/package.json @@ -9,6 +9,7 @@ "custom-env-windows": "custom-env.bat", "path-env": "path-env", "path-env-windows": "path-env.bat", + "repeat-args": "node repeat-args.js", "special-env-variables": "special-env-variables", "special-env-variables-windows": "special-env-variables.bat", "pwd": "pwd", diff --git a/test/fixtures/run-script/repeat-args.js b/test/fixtures/run-script/repeat-args.js new file mode 100755 index 00000000000000..0a5cf7fd80a6b9 --- /dev/null +++ b/test/fixtures/run-script/repeat-args.js @@ -0,0 +1,3 @@ +#!/usr/bin/env node + +console.log(JSON.stringify(process.argv.slice(2))); diff --git a/test/parallel/test-node-run.js b/test/parallel/test-node-run.js index 26295256849702..34597078d59e42 100644 --- a/test/parallel/test-node-run.js +++ b/test/parallel/test-node-run.js @@ -156,6 +156,20 @@ describe('node --run [command]', () => { assert.strictEqual(child.code, 0); }); + it('handles positional arguments with quotes', async () => { + const child = await common.spawnPromisified( + process.execPath, + [ '--run', 'repeat-args', '--', 'I think therefore I\'m'], + { cwd: fixtures.path('run-script') }, + ); + assert.deepStrictEqual(child, { + stdout: `["I think therefore I'm"]\n`, + stderr: '', + code: 0, + signal: null, + }); + }); + it('should set PATH environment variable with paths appended with node_modules/.bin', async () => { const child = await common.spawnPromisified( process.execPath,