| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent c308862 commit 65fbe94
46 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -27,16 +27,17 @@ if (common.isWindows) | |||
| 27 | 27 | const assert = require('assert'); | |
| 28 | 28 | const exec = require('child_process').exec; | |
| 29 | 29 | ||
| 30 | - let cmdline = `ulimit -c 0; ${process.execPath}`; | ||
| 31 | - cmdline += ' --max-old-space-size=16 --max-semi-space-size=4'; | ||
| 32 | - cmdline += ' -e "a = []; for (i = 0; i < 1e9; i++) { a.push({}) }"'; | ||
| 30 | + const cmdline = | ||
| 31 | + common.escapePOSIXShell`ulimit -c 0; "${ | ||
| 32 | + process.execPath | ||
| 33 | + }" --max-old-space-size=16 --max-semi-space-size=4 -e "a = []; for (i = 0; i < 1e9; i++) { a.push({}) }"`; | ||
| 33 | 34 | ||
| 34 | - exec(cmdline, function(err, stdout, stderr) { | ||
| 35 | + exec(...cmdline, common.mustCall((err, stdout, stderr) => { | ||
| 35 | 36 | if (!err) { | |
| 36 | 37 | console.log(stdout); | |
| 37 | 38 | console.log(stderr); | |
| 38 | 39 | assert(false, 'this test should fail'); | |
| 39 | 40 | } | |
| 40 | 41 | ||
| 41 | 42 | assert(common.nodeProcessAborted(err.code, err.signal)); | |
| 42 | - }); | ||
| 43 | + })); | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -62,12 +62,14 @@ assert.ok(!arg); | |||
| 62 | 62 | let program = process.execPath; | |
| 63 | 63 | let args = [ | |
| 64 | 64 | '--abort-on-uncaught-exception', __filename, 'test_callback_abort' ]; | |
| 65 | - const options = { encoding: 'utf8' }; | ||
| 65 | + let options = {}; | ||
| 66 | 66 | if (!common.isWindows) { | |
| 67 | - program = `ulimit -c 0 && exec ${program} ${args.join(' ')}`; | ||
| 67 | + [program, options] = common.escapePOSIXShell`ulimit -c 0 && exec "${program}" ${args[0]} "${args[1]}" ${args[2]}`; | ||
| 68 | 68 | args = []; | |
| 69 | 69 | options.shell = true; | |
| 70 | 70 | } | |
| 71 | + | ||
| 72 | + options.encoding = 'utf8'; | ||
| 71 | 73 | const child = spawnSync(program, args, options); | |
| 72 | 74 | if (common.isWindows) { | |
| 73 | 75 | assert.strictEqual(child.status, 134); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -112,6 +112,33 @@ Creates a 10 MiB file of all null characters. | |||
| 112 | 112 | ||
| 113 | 113 | Indicates if there is more than 1gb of total memory. | |
| 114 | 114 | ||
| 115 | + ### ``escapePOSIXShell`shell command` `` | ||
| 116 | + | ||
| 117 | + Escapes values in a string template literal to pass them as env variable. On Windows, this function | ||
| 118 | + does not escape anything (which is fine for most paths, as `"` is not a valid | ||
| 119 | + char in a path on Windows), so for tests that must pass on Windows, you should | ||
| 120 | + use it only to escape paths, inside double quotes. | ||
| 121 | + This function is meant to be used for tagged template strings. | ||
| 122 | + | ||
| 123 | + ```js | ||
| 124 | + const { escapePOSIXShell } = require('../common'); | ||
| 125 | + const fixtures = require('../common/fixtures'); | ||
| 126 | + const { execSync } = require('node:child_process'); | ||
| 127 | + const origin = fixtures.path('origin'); | ||
| 128 | + const destination = fixtures.path('destination'); | ||
| 129 | + | ||
| 130 | + execSync(...escapePOSIXShell`cp "${origin}" "${destination}"`); | ||
| 131 | + | ||
| 132 | + // When you need to specify specific options, and/or additional env variables: | ||
| 133 | + const [cmd, opts] = escapePOSIXShell`cp "${origin}" "${destination}"`; | ||
| 134 | + console.log(typeof cmd === 'string'); // true | ||
| 135 | + console.log(opts === undefined || typeof opts.env === 'object'); // true | ||
| 136 | + execSync(cmd, { ...opts, stdio: 'ignore' }); | ||
| 137 | + execSync(cmd, { stdio: 'ignore', env: { ...opts?.env, KEY: 'value' } }); | ||
| 138 | + ``` | ||
| 139 | + | ||
| 140 | + When possible, avoid using a shell; that way, there's no need to escape values. | ||
| 141 | + | ||
| 115 | 142 | ### `expectsError(validator[, exact])` | |
| 116 | 143 | ||
| 117 | 144 | * `validator` [\<Object>][<Object>] | [\<RegExp>][<RegExp>] | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -249,15 +249,13 @@ const PIPE = (() => { | |||
| 249 | 249 | // `$node --abort-on-uncaught-exception $file child` | |
| 250 | 250 | // the process aborts. | |
| 251 | 251 | function childShouldThrowAndAbort() { | |
| 252 | - let testCmd = ''; | ||
| 252 | + const escapedArgs = escapePOSIXShell`"${process.argv[0]}" --abort-on-uncaught-exception "${process.argv[1]}" child`; | ||
| 253 | 253 | if (!isWindows) { | |
| 254 | 254 | // Do not create core files, as it can take a lot of disk space on | |
| 255 | 255 | // continuous testing and developers' machines | |
| 256 | - testCmd += 'ulimit -c 0 && '; | ||
| 256 | + escapedArgs[0] = 'ulimit -c 0 && ' + escapedArgs[0]; | ||
| 257 | 257 | } | |
| 258 | - testCmd += `"${process.argv[0]}" --abort-on-uncaught-exception `; | ||
| 259 | - testCmd += `"${process.argv[1]}" child`; | ||
| 260 | - const child = exec(testCmd); | ||
| 258 | + const child = exec(...escapedArgs); | ||
| 261 | 259 | child.on('exit', function onExit(exitCode, signal) { | |
| 262 | 260 | const errMsg = 'Test should have aborted ' + | |
| 263 | 261 | `but instead exited with exit code ${exitCode}` + | |
@@ -888,6 +886,32 @@ function spawnPromisified(...args) { | |||
| 888 | 886 | }); | |
| 889 | 887 | } | |
| 890 | 888 | ||
| 889 | + /** | ||
| 890 | + * Escape values in a string template literal. On Windows, this function | ||
| 891 | + * does not escape anything (which is fine for paths, as `"` is not a valid char | ||
| 892 | + * in a path on Windows), so you should use it only to escape paths – or other | ||
| 893 | + * values on tests which are skipped on Windows. | ||
| 894 | + * This function is meant to be used for tagged template strings. | ||
| 895 | + * @returns {[string, object | undefined]} An array that can be passed as | ||
| 896 | + * arguments to `exec` or `execSync`. | ||
| 897 | + */ | ||
| 898 | + function escapePOSIXShell(cmdParts, ...args) { | ||
| 899 | + if (common.isWindows) { | ||
| 900 | + // On Windows, paths cannot contain `"`, so we can return the string unchanged. | ||
| 901 | + return [String.raw({ raw: cmdParts }, ...args)]; | ||
| 902 | + } | ||
| 903 | + // On POSIX shells, we can pass values via the env, as there's a standard way for referencing a variable. | ||
| 904 | + const env = { ...process.env }; | ||
| 905 | + let cmd = cmdParts[0]; | ||
| 906 | + for (let i = 0; i < args.length; i++) { | ||
| 907 | + const envVarName = `ESCAPED_${i}`; | ||
| 908 | + env[envVarName] = args[i]; | ||
| 909 | + cmd += '${' + envVarName + '}' + cmdParts[i + 1]; | ||
| 910 | + } | ||
| 911 | + | ||
| 912 | + return [cmd, { env }]; | ||
| 913 | + }; | ||
| 914 | + | ||
| 891 | 915 | function getPrintedStackTrace(stderr) { | |
| 892 | 916 | const lines = stderr.split('\n'); | |
| 893 | 917 | ||
@@ -951,6 +975,7 @@ const common = { | |||
| 951 | 975 | childShouldThrowAndAbort, | |
| 952 | 976 | createZeroFilledFile, | |
| 953 | 977 | defaultAutoSelectFamilyAttemptTimeout, | |
| 978 | + escapePOSIXShell, | ||
| 954 | 979 | expectsError, | |
| 955 | 980 | expectRequiredModule, | |
| 956 | 981 | expectWarning, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -11,6 +11,7 @@ const { | |||
| 11 | 11 | childShouldThrowAndAbort, | |
| 12 | 12 | createZeroFilledFile, | |
| 13 | 13 | enoughTestMem, | |
| 14 | + escapePOSIXShell, | ||
| 14 | 15 | expectsError, | |
| 15 | 16 | expectWarning, | |
| 16 | 17 | getArrayBufferViews, | |
@@ -64,6 +65,7 @@ export { | |||
| 64 | 65 | createRequire, | |
| 65 | 66 | createZeroFilledFile, | |
| 66 | 67 | enoughTestMem, | |
| 68 | + escapePOSIXShell, | ||
| 67 | 69 | expectsError, | |
| 68 | 70 | expectWarning, | |
| 69 | 71 | getArrayBufferViews, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -27,7 +27,8 @@ ChildProcess.prototype.spawn = function() { | |||
| 27 | 27 | }; | |
| 28 | 28 | ||
| 29 | 29 | function createChild(options, callback) { | |
| 30 | - const cmd = `"${process.execPath}" "${__filename}" child`; | ||
| 30 | + const [cmd, opts] = common.escapePOSIXShell`"${process.execPath}" "${__filename}" child`; | ||
| 31 | + options = { ...options, env: { ...opts?.env, ...options.env } }; | ||
| 31 | 32 | ||
| 32 | 33 | return cp.exec(cmd, options, common.mustCall(callback)); | |
| 33 | 34 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -13,7 +13,8 @@ if (process.argv[2] === 'child') { | |||
| 13 | 13 | const expectedStdout = `${stdoutData}\n`; | |
| 14 | 14 | const expectedStderr = `${stderrData}\n`; | |
| 15 | 15 | function run(options, callback) { | |
| 16 | - const cmd = `"${process.execPath}" "${__filename}" child`; | ||
| 16 | + const [cmd, opts] = common.escapePOSIXShell`"${process.execPath}" "${__filename}" child`; | ||
| 17 | + options = { ...options, env: { ...opts?.env, ...options.env } }; | ||
| 17 | 18 | ||
| 18 | 19 | cp.exec(cmd, options, common.mustSucceed((stdout, stderr) => { | |
| 19 | 20 | callback(stdout, stderr); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -14,14 +14,15 @@ function runChecks(err, stdio, streamName, expected) { | |||
| 14 | 14 | // On non-Windows, we can pass the path via the env; `"` is not a valid char on | |
| 15 | 15 | // Windows, so we can simply pass the path. | |
| 16 | 16 | const execNode = (args, optionsOrCallback, callback) => { | |
| 17 | + const [cmd, opts] = common.escapePOSIXShell`"${process.execPath}" `; | ||
| 17 | 18 | let options = optionsOrCallback; | |
| 18 | 19 | if (typeof optionsOrCallback === 'function') { | |
| 19 | 20 | options = undefined; | |
| 20 | 21 | callback = optionsOrCallback; | |
| 21 | 22 | } | |
| 22 | 23 | return cp.exec( | |
| 23 | - `"${common.isWindows ? process.execPath : '$NODE'}" ${args}`, | ||
| 24 | - common.isWindows ? options : { ...options, env: { ...process.env, NODE: process.execPath } }, | ||
| 24 | + cmd + args, | ||
| 25 | + { ...opts, ...options }, | ||
| 25 | 26 | callback, | |
| 26 | 27 | ); | |
| 27 | 28 | }; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -12,8 +12,7 @@ if (process.argv[2] === 'child') { | |||
| 12 | 12 | console.log(stdoutData); | |
| 13 | 13 | console.error(stderrData); | |
| 14 | 14 | } else { | |
| 15 | - const cmd = `"${process.execPath}" "${__filename}" child`; | ||
| 16 | - const child = cp.exec(cmd, common.mustSucceed((stdout, stderr) => { | ||
| 15 | + const child = cp.exec(...common.escapePOSIXShell`"${process.execPath}" "${__filename}" child`, common.mustSucceed((stdout, stderr) => { | ||
| 17 | 16 | assert.strictEqual(stdout, expectedStdout); | |
| 18 | 17 | assert.strictEqual(stderr, expectedStderr); | |
| 19 | 18 | })); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -18,9 +18,10 @@ if (process.argv[2] === 'child') { | |||
| 18 | 18 | return; | |
| 19 | 19 | } | |
| 20 | 20 | ||
| 21 | - const cmd = `"${process.execPath}" "${__filename}" child`; | ||
| 21 | + const [cmd, opts] = common.escapePOSIXShell`"${process.execPath}" "${__filename}" child`; | ||
| 22 | 22 | ||
| 23 | 23 | cp.exec(cmd, { | |
| 24 | + ...opts, | ||
| 24 | 25 | timeout: kExpiringParentTimer, | |
| 25 | 26 | }, common.mustCall((err, stdout, stderr) => { | |
| 26 | 27 | console.log('[stdout]', stdout.trim()); | |
| Back | FazBrowse Home | New Git URL |
0 commit comments