mirror of
https://github.com/nodejs/node.git
synced 2024-11-21 10:59:27 +00:00
test: add escapePOSIXShell
util
PR-URL: https://github.com/nodejs/node/pull/55125 Reviewed-By: Jacob Smith <jacob@frende.me> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: LiviaMedeiros <livia@cirno.name> Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
This commit is contained in:
parent
858bce5698
commit
99e0d0d218
@ -27,11 +27,12 @@ if (common.isWindows)
|
||||
const assert = require('assert');
|
||||
const exec = require('child_process').exec;
|
||||
|
||||
let cmdline = `ulimit -c 0; ${process.execPath}`;
|
||||
cmdline += ' --max-old-space-size=16 --max-semi-space-size=4';
|
||||
cmdline += ' -e "a = []; for (i = 0; i < 1e9; i++) { a.push({}) }"';
|
||||
const cmdline =
|
||||
common.escapePOSIXShell`ulimit -c 0; "${
|
||||
process.execPath
|
||||
}" --max-old-space-size=16 --max-semi-space-size=4 -e "a = []; for (i = 0; i < 1e9; i++) { a.push({}) }"`;
|
||||
|
||||
exec(cmdline, function(err, stdout, stderr) {
|
||||
exec(...cmdline, common.mustCall((err, stdout, stderr) => {
|
||||
if (!err) {
|
||||
console.log(stdout);
|
||||
console.log(stderr);
|
||||
@ -39,4 +40,4 @@ exec(cmdline, function(err, stdout, stderr) {
|
||||
}
|
||||
|
||||
assert(common.nodeProcessAborted(err.code, err.signal));
|
||||
});
|
||||
}));
|
||||
|
@ -62,12 +62,14 @@ assert.ok(!arg);
|
||||
let program = process.execPath;
|
||||
let args = [
|
||||
'--abort-on-uncaught-exception', __filename, 'test_callback_abort' ];
|
||||
const options = { encoding: 'utf8' };
|
||||
let options = {};
|
||||
if (!common.isWindows) {
|
||||
program = `ulimit -c 0 && exec ${program} ${args.join(' ')}`;
|
||||
[program, options] = common.escapePOSIXShell`ulimit -c 0 && exec "${program}" ${args[0]} "${args[1]}" ${args[2]}`;
|
||||
args = [];
|
||||
options.shell = true;
|
||||
}
|
||||
|
||||
options.encoding = 'utf8';
|
||||
const child = spawnSync(program, args, options);
|
||||
if (common.isWindows) {
|
||||
assert.strictEqual(child.status, 134);
|
||||
|
@ -112,6 +112,33 @@ Creates a 10 MiB file of all null characters.
|
||||
|
||||
Indicates if there is more than 1gb of total memory.
|
||||
|
||||
### ``escapePOSIXShell`shell command` ``
|
||||
|
||||
Escapes values in a string template literal to pass them as env variable. On Windows, this function
|
||||
does not escape anything (which is fine for most paths, as `"` is not a valid
|
||||
char in a path on Windows), so for tests that must pass on Windows, you should
|
||||
use it only to escape paths, inside double quotes.
|
||||
This function is meant to be used for tagged template strings.
|
||||
|
||||
```js
|
||||
const { escapePOSIXShell } = require('../common');
|
||||
const fixtures = require('../common/fixtures');
|
||||
const { execSync } = require('node:child_process');
|
||||
const origin = fixtures.path('origin');
|
||||
const destination = fixtures.path('destination');
|
||||
|
||||
execSync(...escapePOSIXShell`cp "${origin}" "${destination}"`);
|
||||
|
||||
// When you need to specify specific options, and/or additional env variables:
|
||||
const [cmd, opts] = escapePOSIXShell`cp "${origin}" "${destination}"`;
|
||||
console.log(typeof cmd === 'string'); // true
|
||||
console.log(opts === undefined || typeof opts.env === 'object'); // true
|
||||
execSync(cmd, { ...opts, stdio: 'ignore' });
|
||||
execSync(cmd, { stdio: 'ignore', env: { ...opts?.env, KEY: 'value' } });
|
||||
```
|
||||
|
||||
When possible, avoid using a shell; that way, there's no need to escape values.
|
||||
|
||||
### `expectsError(validator[, exact])`
|
||||
|
||||
* `validator` [\<Object>][<Object>] | [\<RegExp>][<RegExp>] |
|
||||
|
@ -249,15 +249,13 @@ const PIPE = (() => {
|
||||
// `$node --abort-on-uncaught-exception $file child`
|
||||
// the process aborts.
|
||||
function childShouldThrowAndAbort() {
|
||||
let testCmd = '';
|
||||
const escapedArgs = escapePOSIXShell`"${process.argv[0]}" --abort-on-uncaught-exception "${process.argv[1]}" child`;
|
||||
if (!isWindows) {
|
||||
// Do not create core files, as it can take a lot of disk space on
|
||||
// continuous testing and developers' machines
|
||||
testCmd += 'ulimit -c 0 && ';
|
||||
escapedArgs[0] = 'ulimit -c 0 && ' + escapedArgs[0];
|
||||
}
|
||||
testCmd += `"${process.argv[0]}" --abort-on-uncaught-exception `;
|
||||
testCmd += `"${process.argv[1]}" child`;
|
||||
const child = exec(testCmd);
|
||||
const child = exec(...escapedArgs);
|
||||
child.on('exit', function onExit(exitCode, signal) {
|
||||
const errMsg = 'Test should have aborted ' +
|
||||
`but instead exited with exit code ${exitCode}` +
|
||||
@ -888,6 +886,32 @@ function spawnPromisified(...args) {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape values in a string template literal. On Windows, this function
|
||||
* does not escape anything (which is fine for paths, as `"` is not a valid char
|
||||
* in a path on Windows), so you should use it only to escape paths – or other
|
||||
* values on tests which are skipped on Windows.
|
||||
* This function is meant to be used for tagged template strings.
|
||||
* @returns {[string, object | undefined]} An array that can be passed as
|
||||
* arguments to `exec` or `execSync`.
|
||||
*/
|
||||
function escapePOSIXShell(cmdParts, ...args) {
|
||||
if (common.isWindows) {
|
||||
// On Windows, paths cannot contain `"`, so we can return the string unchanged.
|
||||
return [String.raw({ raw: cmdParts }, ...args)];
|
||||
}
|
||||
// On POSIX shells, we can pass values via the env, as there's a standard way for referencing a variable.
|
||||
const env = { ...process.env };
|
||||
let cmd = cmdParts[0];
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
const envVarName = `ESCAPED_${i}`;
|
||||
env[envVarName] = args[i];
|
||||
cmd += '${' + envVarName + '}' + cmdParts[i + 1];
|
||||
}
|
||||
|
||||
return [cmd, { env }];
|
||||
};
|
||||
|
||||
function getPrintedStackTrace(stderr) {
|
||||
const lines = stderr.split('\n');
|
||||
|
||||
@ -951,6 +975,7 @@ const common = {
|
||||
childShouldThrowAndAbort,
|
||||
createZeroFilledFile,
|
||||
defaultAutoSelectFamilyAttemptTimeout,
|
||||
escapePOSIXShell,
|
||||
expectsError,
|
||||
expectRequiredModule,
|
||||
expectWarning,
|
||||
|
@ -11,6 +11,7 @@ const {
|
||||
childShouldThrowAndAbort,
|
||||
createZeroFilledFile,
|
||||
enoughTestMem,
|
||||
escapePOSIXShell,
|
||||
expectsError,
|
||||
expectWarning,
|
||||
getArrayBufferViews,
|
||||
@ -64,6 +65,7 @@ export {
|
||||
createRequire,
|
||||
createZeroFilledFile,
|
||||
enoughTestMem,
|
||||
escapePOSIXShell,
|
||||
expectsError,
|
||||
expectWarning,
|
||||
getArrayBufferViews,
|
||||
|
@ -27,7 +27,8 @@ ChildProcess.prototype.spawn = function() {
|
||||
};
|
||||
|
||||
function createChild(options, callback) {
|
||||
const cmd = `"${process.execPath}" "${__filename}" child`;
|
||||
const [cmd, opts] = common.escapePOSIXShell`"${process.execPath}" "${__filename}" child`;
|
||||
options = { ...options, env: { ...opts?.env, ...options.env } };
|
||||
|
||||
return cp.exec(cmd, options, common.mustCall(callback));
|
||||
}
|
||||
|
@ -13,7 +13,8 @@ if (process.argv[2] === 'child') {
|
||||
const expectedStdout = `${stdoutData}\n`;
|
||||
const expectedStderr = `${stderrData}\n`;
|
||||
function run(options, callback) {
|
||||
const cmd = `"${process.execPath}" "${__filename}" child`;
|
||||
const [cmd, opts] = common.escapePOSIXShell`"${process.execPath}" "${__filename}" child`;
|
||||
options = { ...options, env: { ...opts?.env, ...options.env } };
|
||||
|
||||
cp.exec(cmd, options, common.mustSucceed((stdout, stderr) => {
|
||||
callback(stdout, stderr);
|
||||
|
@ -14,14 +14,15 @@ function runChecks(err, stdio, streamName, expected) {
|
||||
// On non-Windows, we can pass the path via the env; `"` is not a valid char on
|
||||
// Windows, so we can simply pass the path.
|
||||
const execNode = (args, optionsOrCallback, callback) => {
|
||||
const [cmd, opts] = common.escapePOSIXShell`"${process.execPath}" `;
|
||||
let options = optionsOrCallback;
|
||||
if (typeof optionsOrCallback === 'function') {
|
||||
options = undefined;
|
||||
callback = optionsOrCallback;
|
||||
}
|
||||
return cp.exec(
|
||||
`"${common.isWindows ? process.execPath : '$NODE'}" ${args}`,
|
||||
common.isWindows ? options : { ...options, env: { ...process.env, NODE: process.execPath } },
|
||||
cmd + args,
|
||||
{ ...opts, ...options },
|
||||
callback,
|
||||
);
|
||||
};
|
||||
|
@ -12,8 +12,7 @@ if (process.argv[2] === 'child') {
|
||||
console.log(stdoutData);
|
||||
console.error(stderrData);
|
||||
} else {
|
||||
const cmd = `"${process.execPath}" "${__filename}" child`;
|
||||
const child = cp.exec(cmd, common.mustSucceed((stdout, stderr) => {
|
||||
const child = cp.exec(...common.escapePOSIXShell`"${process.execPath}" "${__filename}" child`, common.mustSucceed((stdout, stderr) => {
|
||||
assert.strictEqual(stdout, expectedStdout);
|
||||
assert.strictEqual(stderr, expectedStderr);
|
||||
}));
|
||||
|
@ -18,9 +18,10 @@ if (process.argv[2] === 'child') {
|
||||
return;
|
||||
}
|
||||
|
||||
const cmd = `"${process.execPath}" "${__filename}" child`;
|
||||
const [cmd, opts] = common.escapePOSIXShell`"${process.execPath}" "${__filename}" child`;
|
||||
|
||||
cp.exec(cmd, {
|
||||
...opts,
|
||||
timeout: kExpiringParentTimer,
|
||||
}, common.mustCall((err, stdout, stderr) => {
|
||||
console.log('[stdout]', stdout.trim());
|
||||
|
@ -18,10 +18,11 @@ if (process.argv[2] === 'child') {
|
||||
return;
|
||||
}
|
||||
|
||||
const cmd = `"${process.execPath}" "${__filename}" child`;
|
||||
const [cmd, opts] = common.escapePOSIXShell`"${process.execPath}" "${__filename}" child`;
|
||||
|
||||
// Test with a different kill signal.
|
||||
cp.exec(cmd, {
|
||||
...opts,
|
||||
timeout: kExpiringParentTimer,
|
||||
killSignal: 'SIGKILL'
|
||||
}, common.mustCall((err, stdout, stderr) => {
|
||||
|
@ -22,10 +22,11 @@ if (process.argv[2] === 'child') {
|
||||
return;
|
||||
}
|
||||
|
||||
const cmd = `"${process.execPath}" "${__filename}" child`;
|
||||
const [cmd, opts] = common.escapePOSIXShell`"${process.execPath}" "${__filename}" child`;
|
||||
|
||||
cp.exec(cmd, {
|
||||
timeout: kTimeoutNotSupposedToExpire
|
||||
...opts,
|
||||
timeout: kTimeoutNotSupposedToExpire,
|
||||
}, common.mustSucceed((stdout, stderr) => {
|
||||
assert.strictEqual(stdout.trim(), 'child stdout');
|
||||
assert.strictEqual(stderr.trim(), 'child stderr');
|
||||
|
@ -1,5 +1,5 @@
|
||||
'use strict';
|
||||
require('../common');
|
||||
const { escapePOSIXShell } = require('../common');
|
||||
|
||||
// This test checks that the maxBuffer option for child_process.spawnSync()
|
||||
// works as expected.
|
||||
@ -10,15 +10,12 @@ const { execSync } = require('child_process');
|
||||
const msgOut = 'this is stdout';
|
||||
const msgOutBuf = Buffer.from(`${msgOut}\n`);
|
||||
|
||||
const args = [
|
||||
'-e',
|
||||
`"console.log('${msgOut}')";`,
|
||||
];
|
||||
const [cmd, opts] = escapePOSIXShell`"${process.execPath}" -e "${`console.log('${msgOut}')`}"`;
|
||||
|
||||
// Verify that an error is returned if maxBuffer is surpassed.
|
||||
{
|
||||
assert.throws(() => {
|
||||
execSync(`"${process.execPath}" ${args.join(' ')}`, { maxBuffer: 1 });
|
||||
execSync(cmd, { ...opts, maxBuffer: 1 });
|
||||
}, (e) => {
|
||||
assert.ok(e, 'maxBuffer should error');
|
||||
assert.strictEqual(e.code, 'ENOBUFS');
|
||||
@ -33,8 +30,8 @@ const args = [
|
||||
// Verify that a maxBuffer size of Infinity works.
|
||||
{
|
||||
const ret = execSync(
|
||||
`"${process.execPath}" ${args.join(' ')}`,
|
||||
{ maxBuffer: Infinity }
|
||||
cmd,
|
||||
{ ...opts, maxBuffer: Infinity },
|
||||
);
|
||||
|
||||
assert.deepStrictEqual(ret, msgOutBuf);
|
||||
@ -43,9 +40,7 @@ const args = [
|
||||
// Default maxBuffer size is 1024 * 1024.
|
||||
{
|
||||
assert.throws(() => {
|
||||
execSync(
|
||||
`"${process.execPath}" -e "console.log('a'.repeat(1024 * 1024))"`
|
||||
);
|
||||
execSync(...escapePOSIXShell`"${process.execPath}" -e "console.log('a'.repeat(1024 * 1024))"`);
|
||||
}, (e) => {
|
||||
assert.ok(e, 'maxBuffer should error');
|
||||
assert.strictEqual(e.code, 'ENOBUFS');
|
||||
@ -56,9 +51,7 @@ const args = [
|
||||
|
||||
// Default maxBuffer size is 1024 * 1024.
|
||||
{
|
||||
const ret = execSync(
|
||||
`"${process.execPath}" -e "console.log('a'.repeat(1024 * 1024 - 1))"`
|
||||
);
|
||||
const ret = execSync(...escapePOSIXShell`"${process.execPath}" -e "console.log('a'.repeat(1024 * 1024 - 1))"`);
|
||||
|
||||
assert.deepStrictEqual(
|
||||
ret.toString().trim(),
|
||||
|
@ -7,16 +7,8 @@ const { promisify } = require('util');
|
||||
const exec = promisify(child_process.exec);
|
||||
const execFile = promisify(child_process.execFile);
|
||||
|
||||
// The execPath might contain chars that should be escaped in a shell context.
|
||||
// On non-Windows, we can pass the path via the env; `"` is not a valid char on
|
||||
// Windows, so we can simply pass the path.
|
||||
const execNode = (args) => exec(
|
||||
`"${common.isWindows ? process.execPath : '$NODE'}" ${args}`,
|
||||
common.isWindows ? undefined : { env: { ...process.env, NODE: process.execPath } },
|
||||
);
|
||||
|
||||
{
|
||||
const promise = execNode('-p 42');
|
||||
const promise = exec(...common.escapePOSIXShell`"${process.execPath}" -p 42`);
|
||||
|
||||
assert(promise.child instanceof child_process.ChildProcess);
|
||||
promise.then(common.mustCall((obj) => {
|
||||
@ -53,7 +45,7 @@ const execNode = (args) => exec(
|
||||
const failingCodeWithStdoutErr =
|
||||
'console.log(42);console.error(43);process.exit(1)';
|
||||
{
|
||||
execNode(`-e "${failingCodeWithStdoutErr}"`)
|
||||
exec(...common.escapePOSIXShell`"${process.execPath}" -e "${failingCodeWithStdoutErr}"`)
|
||||
.catch(common.mustCall((err) => {
|
||||
assert.strictEqual(err.code, 1);
|
||||
assert.strictEqual(err.stdout, '42\n');
|
||||
|
@ -32,7 +32,6 @@ const assert = require('assert');
|
||||
const child = require('child_process');
|
||||
const path = require('path');
|
||||
const fixtures = require('../common/fixtures');
|
||||
const nodejs = `"${process.execPath}"`;
|
||||
|
||||
if (process.argv.length > 2) {
|
||||
console.log(process.argv.slice(2).join(' '));
|
||||
@ -40,13 +39,13 @@ if (process.argv.length > 2) {
|
||||
}
|
||||
|
||||
// Assert that nothing is written to stdout.
|
||||
child.exec(`${nodejs} --eval 42`, common.mustSucceed((stdout, stderr) => {
|
||||
child.exec(...common.escapePOSIXShell`"${process.execPath}" --eval 42`, common.mustSucceed((stdout, stderr) => {
|
||||
assert.strictEqual(stdout, '');
|
||||
assert.strictEqual(stderr, '');
|
||||
}));
|
||||
|
||||
// Assert that "42\n" is written to stderr.
|
||||
child.exec(`${nodejs} --eval "console.error(42)"`,
|
||||
child.exec(...common.escapePOSIXShell`"${process.execPath}" --eval "console.error(42)"`,
|
||||
common.mustSucceed((stdout, stderr) => {
|
||||
assert.strictEqual(stdout, '');
|
||||
assert.strictEqual(stderr, '42\n');
|
||||
@ -54,14 +53,14 @@ child.exec(`${nodejs} --eval "console.error(42)"`,
|
||||
|
||||
// Assert that the expected output is written to stdout.
|
||||
['--print', '-p -e', '-pe', '-p'].forEach((s) => {
|
||||
const cmd = `${nodejs} ${s} `;
|
||||
const [cmd, opts] = common.escapePOSIXShell`"${process.execPath}" ${s}`;
|
||||
|
||||
child.exec(`${cmd}42`, common.mustSucceed((stdout, stderr) => {
|
||||
child.exec(`${cmd} 42`, opts, common.mustSucceed((stdout, stderr) => {
|
||||
assert.strictEqual(stdout, '42\n');
|
||||
assert.strictEqual(stderr, '');
|
||||
}));
|
||||
|
||||
child.exec(`${cmd} '[]'`, common.mustSucceed((stdout, stderr) => {
|
||||
child.exec(`${cmd} '[]'`, opts, common.mustSucceed((stdout, stderr) => {
|
||||
assert.strictEqual(stdout, '[]\n');
|
||||
assert.strictEqual(stderr, '');
|
||||
}));
|
||||
@ -69,29 +68,26 @@ child.exec(`${nodejs} --eval "console.error(42)"`,
|
||||
|
||||
// Assert that module loading works.
|
||||
{
|
||||
// Replace \ by / because Windows uses backslashes in paths, but they're still
|
||||
// interpreted as the escape character when put between quotes.
|
||||
const filename = __filename.replace(/\\/g, '/');
|
||||
|
||||
child.exec(`${nodejs} --eval "require('${filename}')"`,
|
||||
common.mustCall((err, stdout, stderr) => {
|
||||
assert.strictEqual(err.code, 42);
|
||||
assert.strictEqual(
|
||||
stdout, 'Loaded as a module, exiting with status code 42.\n');
|
||||
assert.strictEqual(stderr, '');
|
||||
}));
|
||||
common.spawnPromisified(process.execPath, ['--eval', `require(${JSON.stringify(__filename)})`])
|
||||
.then(common.mustCall(({ stdout, stderr, code }) => {
|
||||
assert.strictEqual(stderr, '');
|
||||
assert.strictEqual(
|
||||
stdout, 'Loaded as a module, exiting with status code 42.\n');
|
||||
assert.strictEqual(code, 42);
|
||||
}));
|
||||
}
|
||||
|
||||
// Check that builtin modules are pre-defined.
|
||||
child.exec(`${nodejs} --print "os.platform()"`,
|
||||
child.exec(...common.escapePOSIXShell`"${process.execPath}" --print "os.platform()"`,
|
||||
common.mustSucceed((stdout, stderr) => {
|
||||
assert.strictEqual(stderr, '');
|
||||
assert.strictEqual(stdout.trim(), require('os').platform());
|
||||
}));
|
||||
|
||||
// Module path resolve bug regression test.
|
||||
child.exec(`${nodejs} --eval "require('./test/parallel/test-cli-eval.js')"`,
|
||||
{ cwd: path.resolve(__dirname, '../../') },
|
||||
const [cmd, opts] = common.escapePOSIXShell`"${process.execPath}" --eval "require('./test/parallel/test-cli-eval.js')"`;
|
||||
child.exec(cmd,
|
||||
{ ...opts, cwd: path.resolve(__dirname, '../../') },
|
||||
common.mustCall((err, stdout, stderr) => {
|
||||
assert.strictEqual(err.code, 42);
|
||||
assert.strictEqual(
|
||||
@ -100,7 +96,7 @@ child.exec(`${nodejs} --eval "require('./test/parallel/test-cli-eval.js')"`,
|
||||
}));
|
||||
|
||||
// Missing argument should not crash.
|
||||
child.exec(`${nodejs} -e`, common.mustCall((err, stdout, stderr) => {
|
||||
child.exec(...common.escapePOSIXShell`"${process.execPath}" -e`, common.mustCall((err, stdout, stderr) => {
|
||||
assert.strictEqual(err.code, 9);
|
||||
assert.strictEqual(stdout, '');
|
||||
assert.strictEqual(stderr.trim(),
|
||||
@ -108,18 +104,18 @@ child.exec(`${nodejs} -e`, common.mustCall((err, stdout, stderr) => {
|
||||
}));
|
||||
|
||||
// Empty program should do nothing.
|
||||
child.exec(`${nodejs} -e ""`, common.mustSucceed((stdout, stderr) => {
|
||||
child.exec(...common.escapePOSIXShell`"${process.execPath}" -e ""`, common.mustSucceed((stdout, stderr) => {
|
||||
assert.strictEqual(stdout, '');
|
||||
assert.strictEqual(stderr, '');
|
||||
}));
|
||||
|
||||
// "\\-42" should be interpreted as an escaped expression, not a switch.
|
||||
child.exec(`${nodejs} -p "\\-42"`, common.mustSucceed((stdout, stderr) => {
|
||||
child.exec(...common.escapePOSIXShell`"${process.execPath}" -p "\\-42"`, common.mustSucceed((stdout, stderr) => {
|
||||
assert.strictEqual(stdout, '-42\n');
|
||||
assert.strictEqual(stderr, '');
|
||||
}));
|
||||
|
||||
child.exec(`${nodejs} --use-strict -p process.execArgv`,
|
||||
child.exec(...common.escapePOSIXShell`"${process.execPath}" --use-strict -p process.execArgv`,
|
||||
common.mustSucceed((stdout, stderr) => {
|
||||
assert.strictEqual(
|
||||
stdout, "[ '--use-strict', '-p', 'process.execArgv' ]\n"
|
||||
@ -129,26 +125,26 @@ child.exec(`${nodejs} --use-strict -p process.execArgv`,
|
||||
|
||||
// Regression test for https://github.com/nodejs/node/issues/3574.
|
||||
{
|
||||
let emptyFile = fixtures.path('empty.js');
|
||||
if (common.isWindows) {
|
||||
emptyFile = emptyFile.replace(/\\/g, '\\\\');
|
||||
}
|
||||
const emptyFile = fixtures.path('empty.js');
|
||||
|
||||
child.exec(`${nodejs} -e 'require("child_process").fork("${emptyFile}")'`,
|
||||
common.mustSucceed((stdout, stderr) => {
|
||||
assert.strictEqual(stdout, '');
|
||||
assert.strictEqual(stderr, '');
|
||||
}));
|
||||
common.spawnPromisified(process.execPath, ['-e', `require("child_process").fork(${JSON.stringify(emptyFile)})`])
|
||||
.then(common.mustCall(({ stdout, stderr, code }) => {
|
||||
assert.strictEqual(stdout, '');
|
||||
assert.strictEqual(stderr, '');
|
||||
assert.strictEqual(code, 0);
|
||||
}));
|
||||
|
||||
// Make sure that monkey-patching process.execArgv doesn't cause child_process
|
||||
// to incorrectly munge execArgv.
|
||||
child.exec(
|
||||
`${nodejs} -e "process.execArgv = ['-e', 'console.log(42)', 'thirdArg'];` +
|
||||
`require('child_process').fork('${emptyFile}')"`,
|
||||
common.mustSucceed((stdout, stderr) => {
|
||||
assert.strictEqual(stdout, '42\n');
|
||||
assert.strictEqual(stderr, '');
|
||||
}));
|
||||
common.spawnPromisified(process.execPath, [
|
||||
'-e',
|
||||
'process.execArgv = [\'-e\', \'console.log(42)\', \'thirdArg\'];' +
|
||||
`require('child_process').fork(${JSON.stringify(emptyFile)})`,
|
||||
]).then(common.mustCall(({ stdout, stderr, code }) => {
|
||||
assert.strictEqual(stdout, '42\n');
|
||||
assert.strictEqual(stderr, '');
|
||||
assert.strictEqual(code, 0);
|
||||
}));
|
||||
}
|
||||
|
||||
// Regression test for https://github.com/nodejs/node/issues/8534.
|
||||
@ -192,32 +188,34 @@ child.exec(`${nodejs} --use-strict -p process.execArgv`,
|
||||
].forEach(function(args) {
|
||||
|
||||
// Ensure that arguments are successfully passed to eval.
|
||||
const opt = ' --eval "console.log(process.argv.slice(1).join(\' \'))"';
|
||||
const cmd = `${nodejs}${opt} -- ${args}`;
|
||||
child.exec(cmd, common.mustCall(function(err, stdout, stderr) {
|
||||
assert.strictEqual(stdout, `${args}\n`);
|
||||
assert.strictEqual(stderr, '');
|
||||
assert.strictEqual(err, null);
|
||||
}));
|
||||
child.exec(
|
||||
...common.escapePOSIXShell`"${process.execPath}" --eval "console.log(process.argv.slice(1).join(' '))" -- ${args}`,
|
||||
common.mustCall(function(err, stdout, stderr) {
|
||||
assert.strictEqual(stdout, `${args}\n`);
|
||||
assert.strictEqual(stderr, '');
|
||||
assert.strictEqual(err, null);
|
||||
})
|
||||
);
|
||||
|
||||
// Ensure that arguments are successfully passed to print.
|
||||
const popt = ' --print "process.argv.slice(1).join(\' \')"';
|
||||
const pcmd = `${nodejs}${popt} -- ${args}`;
|
||||
child.exec(pcmd, common.mustCall(function(err, stdout, stderr) {
|
||||
assert.strictEqual(stdout, `${args}\n`);
|
||||
assert.strictEqual(stderr, '');
|
||||
assert.strictEqual(err, null);
|
||||
}));
|
||||
child.exec(
|
||||
...common.escapePOSIXShell`"${process.execPath}" --print "process.argv.slice(1).join(' ')" -- ${args}`,
|
||||
common.mustCall(function(err, stdout, stderr) {
|
||||
assert.strictEqual(stdout, `${args}\n`);
|
||||
assert.strictEqual(stderr, '');
|
||||
assert.strictEqual(err, null);
|
||||
})
|
||||
);
|
||||
|
||||
// Ensure that arguments are successfully passed to a script.
|
||||
// The first argument after '--' should be interpreted as a script
|
||||
// filename.
|
||||
const filecmd = `${nodejs} -- "${__filename}" ${args}`;
|
||||
child.exec(filecmd, common.mustCall(function(err, stdout, stderr) {
|
||||
assert.strictEqual(stdout, `${args}\n`);
|
||||
assert.strictEqual(stderr, '');
|
||||
assert.strictEqual(err, null);
|
||||
}));
|
||||
child.exec(...common.escapePOSIXShell`"${process.execPath}" -- "${__filename}" ${args}`,
|
||||
common.mustCall(function(err, stdout, stderr) {
|
||||
assert.strictEqual(stdout, `${args}\n`);
|
||||
assert.strictEqual(stderr, '');
|
||||
assert.strictEqual(err, null);
|
||||
}));
|
||||
});
|
||||
|
||||
// ESModule eval tests
|
||||
@ -226,14 +224,14 @@ child.exec(`${nodejs} --use-strict -p process.execArgv`,
|
||||
// Assert that "42\n" is written to stdout on module eval.
|
||||
const execOptions = '--input-type module';
|
||||
child.exec(
|
||||
`${nodejs} ${execOptions} --eval "console.log(42)"`,
|
||||
...common.escapePOSIXShell`"${process.execPath}" ${execOptions} --eval "console.log(42)"`,
|
||||
common.mustSucceed((stdout) => {
|
||||
assert.strictEqual(stdout, '42\n');
|
||||
}));
|
||||
|
||||
// Assert that "42\n" is written to stdout with print option.
|
||||
child.exec(
|
||||
`${nodejs} ${execOptions} --print --eval "42"`,
|
||||
...common.escapePOSIXShell`"${process.execPath}" ${execOptions} --print --eval "42"`,
|
||||
common.mustCall((err, stdout, stderr) => {
|
||||
assert.ok(err);
|
||||
assert.strictEqual(stdout, '');
|
||||
@ -242,7 +240,7 @@ child.exec(
|
||||
|
||||
// Assert that error is written to stderr on invalid input.
|
||||
child.exec(
|
||||
`${nodejs} ${execOptions} --eval "!!!!"`,
|
||||
...common.escapePOSIXShell`"${process.execPath}" ${execOptions} --eval "!!!!"`,
|
||||
common.mustCall((err, stdout, stderr) => {
|
||||
assert.ok(err);
|
||||
assert.strictEqual(stdout, '');
|
||||
@ -251,100 +249,95 @@ child.exec(
|
||||
|
||||
// Assert that require is undefined in ESM support
|
||||
child.exec(
|
||||
`${nodejs} ${execOptions} --eval "console.log(typeof require);"`,
|
||||
...common.escapePOSIXShell`"${process.execPath}" ${execOptions} --eval "console.log(typeof require);"`,
|
||||
common.mustSucceed((stdout) => {
|
||||
assert.strictEqual(stdout, 'undefined\n');
|
||||
}));
|
||||
|
||||
// Assert that import.meta is defined in ESM
|
||||
child.exec(
|
||||
`${nodejs} ${execOptions} --eval "console.log(typeof import.meta);"`,
|
||||
...common.escapePOSIXShell`"${process.execPath}" ${execOptions} --eval "console.log(typeof import.meta);"`,
|
||||
common.mustSucceed((stdout) => {
|
||||
assert.strictEqual(stdout, 'object\n');
|
||||
}));
|
||||
|
||||
{
|
||||
// Assert that packages can be imported cwd-relative with --eval
|
||||
child.exec(
|
||||
`${nodejs} ${execOptions} ` +
|
||||
'--eval "import \'./test/fixtures/es-modules/mjs-file.mjs\'"',
|
||||
common.mustSucceed((stdout) => {
|
||||
assert.strictEqual(stdout, '.mjs file\n');
|
||||
}));
|
||||
const [cmd, opts] = common.escapePOSIXShell`"${process.execPath}" ${execOptions} --eval`;
|
||||
const options = { ...opts, cwd: path.join(__dirname, '../..') };
|
||||
child.exec(
|
||||
`${cmd} "import './test/fixtures/es-modules/mjs-file.mjs'"`,
|
||||
options,
|
||||
common.mustSucceed((stdout) => {
|
||||
assert.strictEqual(stdout, '.mjs file\n');
|
||||
}));
|
||||
|
||||
|
||||
// Assert that packages can be dynamic imported initial cwd-relative with --eval
|
||||
child.exec(
|
||||
`${nodejs} ${execOptions} ` +
|
||||
'--eval "process.chdir(\'..\');' +
|
||||
// Assert that packages can be dynamic imported initial cwd-relative with --eval
|
||||
child.exec(
|
||||
cmd + ' "process.chdir(\'..\');' +
|
||||
'import(\'./test/fixtures/es-modules/mjs-file.mjs\')"',
|
||||
common.mustSucceed((stdout) => {
|
||||
assert.strictEqual(stdout, '.mjs file\n');
|
||||
}));
|
||||
options,
|
||||
common.mustSucceed((stdout) => {
|
||||
assert.strictEqual(stdout, '.mjs file\n');
|
||||
}));
|
||||
|
||||
child.exec(
|
||||
`${nodejs} ` +
|
||||
'--eval "process.chdir(\'..\');' +
|
||||
child.exec(
|
||||
cmd + ' "process.chdir(\'..\');' +
|
||||
'import(\'./test/fixtures/es-modules/mjs-file.mjs\')"',
|
||||
common.mustSucceed((stdout) => {
|
||||
assert.strictEqual(stdout, '.mjs file\n');
|
||||
}));
|
||||
options,
|
||||
common.mustSucceed((stdout) => {
|
||||
assert.strictEqual(stdout, '.mjs file\n');
|
||||
}));
|
||||
}
|
||||
|
||||
if (common.hasCrypto) {
|
||||
// Assert that calls to crypto utils work without require.
|
||||
child.exec(
|
||||
`${nodejs} ` +
|
||||
'-e "console.log(crypto.randomBytes(16).toString(\'hex\'))"',
|
||||
...common.escapePOSIXShell`"${process.execPath}" -e "console.log(crypto.randomBytes(16).toString('hex'))"`,
|
||||
common.mustSucceed((stdout) => {
|
||||
assert.match(stdout, /[0-9a-f]{32}/i);
|
||||
}));
|
||||
child.exec(
|
||||
`${nodejs} ` +
|
||||
'-p "crypto.randomBytes(16).toString(\'hex\')"',
|
||||
...common.escapePOSIXShell`"${process.execPath}" -p "crypto.randomBytes(16).toString('hex')"`,
|
||||
common.mustSucceed((stdout) => {
|
||||
assert.match(stdout, /[0-9a-f]{32}/i);
|
||||
}));
|
||||
}
|
||||
// Assert that overriding crypto works.
|
||||
child.exec(
|
||||
`${nodejs} ` +
|
||||
'-p "crypto=Symbol(\'test\')"',
|
||||
...common.escapePOSIXShell`"${process.execPath}" -p "crypto=Symbol('test')"`,
|
||||
common.mustSucceed((stdout) => {
|
||||
assert.match(stdout, /Symbol\(test\)/i);
|
||||
}));
|
||||
child.exec(
|
||||
`${nodejs} ` +
|
||||
'-e "crypto = {};console.log(\'randomBytes\', typeof crypto.randomBytes)"',
|
||||
...common.escapePOSIXShell`"${process.execPath}" -e "crypto = {};console.log('randomBytes', typeof crypto.randomBytes)"`,
|
||||
common.mustSucceed((stdout) => {
|
||||
assert.match(stdout, /randomBytes\sundefined/);
|
||||
}));
|
||||
// Assert that overriding crypto with a local variable works.
|
||||
child.exec(
|
||||
`${nodejs} ` +
|
||||
'-e "const crypto = {};console.log(\'randomBytes\', typeof crypto.randomBytes)"',
|
||||
...common.escapePOSIXShell`"${process.execPath}" -e "const crypto = {};console.log('randomBytes', typeof crypto.randomBytes)"`,
|
||||
common.mustSucceed((stdout) => {
|
||||
assert.match(stdout, /randomBytes\sundefined/);
|
||||
}));
|
||||
child.exec(
|
||||
`${nodejs} ` +
|
||||
'-e "let crypto = {};console.log(\'randomBytes\', typeof crypto.randomBytes)"',
|
||||
...common.escapePOSIXShell`"${process.execPath}" -e "let crypto = {};console.log('randomBytes', typeof crypto.randomBytes)"`,
|
||||
common.mustSucceed((stdout) => {
|
||||
assert.match(stdout, /randomBytes\sundefined/);
|
||||
}));
|
||||
child.exec(
|
||||
`${nodejs} ` +
|
||||
'-e "var crypto = {};console.log(\'randomBytes\', typeof crypto.randomBytes)"',
|
||||
...common.escapePOSIXShell`"${process.execPath}" -e "var crypto = {};console.log('randomBytes', typeof crypto.randomBytes)"`,
|
||||
common.mustSucceed((stdout) => {
|
||||
assert.match(stdout, /randomBytes\sundefined/);
|
||||
}));
|
||||
child.exec(
|
||||
`${nodejs} ` +
|
||||
'-p "const crypto = {randomBytes:1};typeof crypto.randomBytes"',
|
||||
...common.escapePOSIXShell`"${process.execPath}" -p "const crypto = {randomBytes:1};typeof crypto.randomBytes"`,
|
||||
common.mustSucceed((stdout) => {
|
||||
assert.match(stdout, /^number/);
|
||||
}));
|
||||
child.exec(
|
||||
`${nodejs} ` +
|
||||
'-p "let crypto = {randomBytes:1};typeof crypto.randomBytes"',
|
||||
...common.escapePOSIXShell`"${process.execPath}" -p "let crypto = {randomBytes:1};typeof crypto.randomBytes"`,
|
||||
common.mustSucceed((stdout) => {
|
||||
assert.match(stdout, /^number/);
|
||||
}));
|
||||
|
@ -11,18 +11,8 @@ const { exec, spawn } = require('child_process');
|
||||
const { once } = require('events');
|
||||
let stdOut;
|
||||
|
||||
// The execPath might contain chars that should be escaped in a shell context.
|
||||
// On non-Windows, we can pass the path via the env; `"` is not a valid char on
|
||||
// Windows, so we can simply pass the path.
|
||||
const execNode = (args, callback) => exec(
|
||||
`"${common.isWindows ? process.execPath : '$NODE'}" ${args}`,
|
||||
common.isWindows ? undefined : { env: { ...process.env, NODE: process.execPath } },
|
||||
callback,
|
||||
);
|
||||
|
||||
|
||||
function startPrintHelpTest() {
|
||||
execNode('--help', common.mustSucceed((stdout, stderr) => {
|
||||
exec(...common.escapePOSIXShell`"${process.execPath}" --help`, common.mustSucceed((stdout, stderr) => {
|
||||
stdOut = stdout;
|
||||
validateNodePrintHelp();
|
||||
}));
|
||||
|
@ -4,21 +4,10 @@ const common = require('../common');
|
||||
const assert = require('assert');
|
||||
const { exec } = require('child_process');
|
||||
|
||||
// The execPath might contain chars that should be escaped in a shell context.
|
||||
// On non-Windows, we can pass the path via the env; `"` is not a valid char on
|
||||
// Windows, so we can simply pass the path.
|
||||
const execNode = (args, callback) => exec(
|
||||
`"${common.isWindows ? process.execPath : '$NODE'}" ${args}`,
|
||||
common.isWindows ? undefined : { env: { ...process.env, NODE: process.execPath } },
|
||||
callback,
|
||||
);
|
||||
|
||||
|
||||
// Should throw if -c and -e flags are both passed
|
||||
['-c', '--check'].forEach(function(checkFlag) {
|
||||
['-e', '--eval'].forEach(function(evalFlag) {
|
||||
const args = [checkFlag, evalFlag, 'foo'];
|
||||
execNode(args.join(' '), common.mustCall((err, stdout, stderr) => {
|
||||
exec(...common.escapePOSIXShell`"${process.execPath}" ${checkFlag} ${evalFlag} foo`, common.mustCall((err, stdout, stderr) => {
|
||||
assert.strictEqual(err instanceof Error, true);
|
||||
assert.strictEqual(err.code, 9);
|
||||
assert(
|
||||
|
@ -621,12 +621,10 @@ assert.throws(
|
||||
const msgfile = tmpdir.resolve('s5.msg');
|
||||
fs.writeFileSync(msgfile, msg);
|
||||
|
||||
const cmd =
|
||||
`"${common.opensslCli}" dgst -sha256 -verify "${pubfile}" -signature "${
|
||||
sigfile}" -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-2 "${
|
||||
msgfile}"`;
|
||||
|
||||
exec(cmd, common.mustCall((err, stdout, stderr) => {
|
||||
exec(...common.escapePOSIXShell`"${
|
||||
common.opensslCli}" dgst -sha256 -verify "${pubfile}" -signature "${
|
||||
sigfile}" -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-2 "${msgfile
|
||||
}"`, common.mustCall((err, stdout, stderr) => {
|
||||
assert(stdout.includes('Verified OK'));
|
||||
}));
|
||||
}
|
||||
|
@ -202,18 +202,15 @@ if (process.argv[2] === 'child') {
|
||||
} else {
|
||||
|
||||
tests.forEach(function(test, testIndex) {
|
||||
let testCmd = '';
|
||||
const escapedArgs = common.escapePOSIXShell`"${process.execPath}" --abort-on-uncaught-exception "${__filename}" child ${testIndex}`;
|
||||
if (!common.isWindows) {
|
||||
// Do not create core files, as it can take a lot of disk space on
|
||||
// continuous testing and developers' machines
|
||||
testCmd += 'ulimit -c 0 && ';
|
||||
escapedArgs[0] = 'ulimit -c 0 && ' + escapedArgs[0];
|
||||
}
|
||||
|
||||
testCmd += `"${process.argv[0]}" --abort-on-uncaught-exception ` +
|
||||
`"${process.argv[1]}" child ${testIndex}`;
|
||||
|
||||
try {
|
||||
child_process.execSync(testCmd);
|
||||
child_process.execSync(...escapedArgs);
|
||||
} catch (e) {
|
||||
assert.fail(`Test index ${testIndex} failed: ${e}`);
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ if (process.argv[2] === 'child') {
|
||||
|
||||
function runTestWithoutAbortOnUncaughtException() {
|
||||
child_process.exec(
|
||||
createTestCmdLine(),
|
||||
...createTestCmdLine(),
|
||||
function onTestDone(err, stdout, stderr) {
|
||||
// When _not_ passing --abort-on-uncaught-exception, the process'
|
||||
// uncaughtException handler _must_ be called, and thus the error
|
||||
@ -70,7 +70,7 @@ function runTestWithoutAbortOnUncaughtException() {
|
||||
}
|
||||
|
||||
function runTestWithAbortOnUncaughtException() {
|
||||
child_process.exec(createTestCmdLine({
|
||||
child_process.exec(...createTestCmdLine({
|
||||
withAbortOnUncaughtException: true
|
||||
}), function onTestDone(err, stdout, stderr) {
|
||||
assert.notStrictEqual(err.code, RAN_UNCAUGHT_EXCEPTION_HANDLER_EXIT_CODE,
|
||||
@ -82,21 +82,14 @@ function runTestWithAbortOnUncaughtException() {
|
||||
}
|
||||
|
||||
function createTestCmdLine(options) {
|
||||
let testCmd = '';
|
||||
const escapedArgs = common.escapePOSIXShell`"${process.execPath}" ${
|
||||
options?.withAbortOnUncaughtException ? '--abort-on-uncaught-exception' : ''
|
||||
} "${__filename}" child`;
|
||||
|
||||
if (!common.isWindows) {
|
||||
// Do not create core files, as it can take a lot of disk space on
|
||||
// continuous testing and developers' machines
|
||||
testCmd += 'ulimit -c 0 && ';
|
||||
escapedArgs[0] = 'ulimit -c 0 && ' + escapedArgs[0];
|
||||
}
|
||||
|
||||
testCmd += `"${process.argv[0]}"`;
|
||||
|
||||
if (options?.withAbortOnUncaughtException) {
|
||||
testCmd += ' --abort-on-uncaught-exception';
|
||||
}
|
||||
|
||||
testCmd += ` "${process.argv[1]}" child`;
|
||||
|
||||
return testCmd;
|
||||
return escapedArgs;
|
||||
}
|
||||
|
@ -91,21 +91,17 @@ if (process.argv[2] === 'child') {
|
||||
if (options.throwInDomainErrHandler)
|
||||
throwInDomainErrHandlerOpt = 'throwInDomainErrHandler';
|
||||
|
||||
let cmdToExec = '';
|
||||
if (!common.isWindows) {
|
||||
// Do not create core files, as it can take a lot of disk space on
|
||||
// continuous testing and developers' machines
|
||||
cmdToExec += 'ulimit -c 0 && ';
|
||||
}
|
||||
|
||||
let useTryCatchOpt;
|
||||
if (options.useTryCatch)
|
||||
useTryCatchOpt = 'useTryCatch';
|
||||
|
||||
cmdToExec += `"${process.argv[0]}" ${cmdLineOption ? cmdLineOption : ''} "${
|
||||
process.argv[1]}" child ${throwInDomainErrHandlerOpt} ${useTryCatchOpt}`;
|
||||
|
||||
const child = exec(cmdToExec);
|
||||
const escapedArgs = common.escapePOSIXShell`"${process.execPath}" ${cmdLineOption || ''} "${__filename}" child ${throwInDomainErrHandlerOpt || ''} ${useTryCatchOpt || ''}`;
|
||||
if (!common.isWindows) {
|
||||
// Do not create core files, as it can take a lot of disk space on
|
||||
// continuous testing and developers' machines
|
||||
escapedArgs[0] = 'ulimit -c 0 && ' + escapedArgs[0];
|
||||
}
|
||||
const child = exec(...escapedArgs);
|
||||
|
||||
if (child) {
|
||||
child.on('exit', function onChildExited(exitCode, signal) {
|
||||
|
@ -7,14 +7,13 @@ if (process.argv[2] === 'child') {
|
||||
process.emitWarning('foo');
|
||||
} else {
|
||||
function test(newEnv) {
|
||||
const env = { ...process.env, ...newEnv };
|
||||
const cmd = `"${process.execPath}" "${__filename}" child`;
|
||||
const [cmd, opts] = common.escapePOSIXShell`"${process.execPath}" "${__filename}" child`;
|
||||
|
||||
cp.exec(cmd, { env }, common.mustCall((err, stdout, stderr) => {
|
||||
cp.exec(cmd, { ...opts, env: { ...opts?.env, ...newEnv } }, common.mustCall((err, stdout, stderr) => {
|
||||
assert.strictEqual(err, null);
|
||||
assert.strictEqual(stdout, '');
|
||||
|
||||
if (env.NODE_NO_WARNINGS === '1')
|
||||
if (newEnv.NODE_NO_WARNINGS === '1')
|
||||
assert.strictEqual(stderr, '');
|
||||
else
|
||||
assert.match(stderr.trim(), /Warning: foo\n/);
|
||||
|
@ -28,8 +28,7 @@ const fixtures = require('../common/fixtures');
|
||||
function errExec(script, option, callback) {
|
||||
callback = typeof option === 'function' ? option : callback;
|
||||
option = typeof option === 'string' ? option : '';
|
||||
const cmd = `"${process.argv[0]}" ${option} "${fixtures.path(script)}"`;
|
||||
return exec(cmd, (err, stdout, stderr) => {
|
||||
return exec(...common.escapePOSIXShell`"${process.execPath}" ${option} "${fixtures.path(script)}"`, (err, stdout, stderr) => {
|
||||
// There was some error
|
||||
assert.ok(err);
|
||||
|
||||
|
@ -198,7 +198,7 @@ if (!common.isWindows) {
|
||||
const filename = `${tmpdir.path}/foo.pipe`;
|
||||
const mkfifoResult = child_process.spawnSync('mkfifo', [filename]);
|
||||
if (!mkfifoResult.error) {
|
||||
child_process.exec(`echo "xyz foobar" > '${filename}'`);
|
||||
child_process.exec(...common.escapePOSIXShell`echo "xyz foobar" > "${filename}"`);
|
||||
const stream = new fs.createReadStream(filename, common.mustNotMutateObjectDeep({ end: 1 }));
|
||||
stream.data = '';
|
||||
|
||||
|
@ -25,21 +25,19 @@ const data2 = 'World';
|
||||
const expected = `${data1}\n${data2}\n`;
|
||||
|
||||
const exec = require('child_process').exec;
|
||||
const f = JSON.stringify(__filename);
|
||||
const node = JSON.stringify(process.execPath);
|
||||
|
||||
function test(child) {
|
||||
const cmd = `(echo ${data1}; sleep 0.5; echo ${data2}) | ${node} ${f} ${child}`;
|
||||
exec(cmd, common.mustSucceed((stdout, stderr) => {
|
||||
assert.strictEqual(
|
||||
stdout,
|
||||
expected,
|
||||
`expected to read(${child === childType[0] ? 'with' : 'without'} encoding): '${expected}' but got: '${stdout}'`);
|
||||
assert.strictEqual(
|
||||
stderr,
|
||||
'',
|
||||
`expected not to read anything from stderr but got: '${stderr}'`);
|
||||
}));
|
||||
exec(...common.escapePOSIXShell`(echo "${data1}"; sleep 0.5; echo "${data2}") | "${process.execPath}" "${__filename}" "${child}"`,
|
||||
common.mustSucceed((stdout, stderr) => {
|
||||
assert.strictEqual(
|
||||
stdout,
|
||||
expected,
|
||||
`expected to read(${child === childType[0] ? 'with' : 'without'} encoding): '${expected}' but got: '${stdout}'`);
|
||||
assert.strictEqual(
|
||||
stderr,
|
||||
'',
|
||||
`expected not to read anything from stderr but got: '${stderr}'`);
|
||||
}));
|
||||
}
|
||||
|
||||
test(childType[0]);
|
||||
|
@ -36,9 +36,7 @@ const fixtures = require('../common/fixtures');
|
||||
|
||||
function test(env, cb) {
|
||||
const filename = fixtures.path('test-fs-readfile-error.js');
|
||||
const execPath = `"${process.execPath}" "${filename}"`;
|
||||
const options = { env: { ...process.env, ...env } };
|
||||
exec(execPath, options, (err, stdout, stderr) => {
|
||||
exec(...common.escapePOSIXShell`"${process.execPath}" "${filename}"`, (err, stdout, stderr) => {
|
||||
assert(err);
|
||||
assert.strictEqual(stdout, '');
|
||||
assert.notStrictEqual(stderr, '');
|
||||
|
@ -25,10 +25,8 @@ tmpdir.refresh();
|
||||
fs.writeFileSync(filename, dataExpected);
|
||||
|
||||
const exec = require('child_process').exec;
|
||||
const f = JSON.stringify(__filename);
|
||||
const node = JSON.stringify(process.execPath);
|
||||
const cmd = `cat ${filename} | ${node} ${f} child`;
|
||||
exec(cmd, { maxBuffer: 1000000 }, common.mustSucceed((stdout, stderr) => {
|
||||
const [cmd, opts] = common.escapePOSIXShell`"${process.execPath}" "${__filename}" child < "${filename}"`;
|
||||
exec(cmd, { ...opts, maxBuffer: 1000000 }, common.mustSucceed((stdout, stderr) => {
|
||||
assert.strictEqual(
|
||||
stdout,
|
||||
dataExpected,
|
||||
|
@ -43,10 +43,7 @@ const filename = fixtures.path('readfile_pipe_test.txt');
|
||||
const dataExpected = fs.readFileSync(filename).toString();
|
||||
|
||||
const exec = require('child_process').exec;
|
||||
const f = JSON.stringify(__filename);
|
||||
const node = JSON.stringify(process.execPath);
|
||||
const cmd = `cat ${filename} | ${node} ${f} child`;
|
||||
exec(cmd, common.mustSucceed((stdout, stderr) => {
|
||||
exec(...common.escapePOSIXShell`"${process.execPath}" "${__filename}" child < "${filename}"`, common.mustSucceed((stdout, stderr) => {
|
||||
assert.strictEqual(
|
||||
stdout,
|
||||
dataExpected,
|
||||
|
@ -22,12 +22,10 @@ tmpdir.refresh();
|
||||
fs.writeFileSync(filename, dataExpected);
|
||||
|
||||
const exec = require('child_process').exec;
|
||||
const f = JSON.stringify(__filename);
|
||||
const node = JSON.stringify(process.execPath);
|
||||
const cmd = `cat ${filename} | ${node} ${f} child`;
|
||||
const [cmd, opts] = common.escapePOSIXShell`"${process.execPath}" "${__filename}" child < "${filename}"`;
|
||||
exec(
|
||||
cmd,
|
||||
{ maxBuffer: 1000000 },
|
||||
{ ...opts, maxBuffer: 1_000_000 },
|
||||
common.mustSucceed((stdout, stderr) => {
|
||||
assert.strictEqual(stdout, dataExpected);
|
||||
assert.strictEqual(stderr, '');
|
||||
|
@ -19,8 +19,8 @@ if (process.argv[2] === 'child') {
|
||||
tmpdir.refresh();
|
||||
fs.writeFileSync(filename, '.'.repeat(1 << 16)); // Exceeds RLIMIT_FSIZE.
|
||||
} else {
|
||||
const cmd = `ulimit -f 1 && '${process.execPath}' '${__filename}' child`;
|
||||
const result = child_process.spawnSync('/bin/sh', ['-c', cmd]);
|
||||
const [cmd, opts] = common.escapePOSIXShell`ulimit -f 1 && "${process.execPath}" "${__filename}" child`;
|
||||
const result = child_process.spawnSync('/bin/sh', ['-c', cmd], opts);
|
||||
const haystack = result.stderr.toString();
|
||||
const needle = 'Error: EFBIG: file too large, write';
|
||||
const ok = haystack.includes(needle);
|
||||
|
@ -15,20 +15,12 @@ if (process.argv[2] === 'child') {
|
||||
assert.ok(process.permission.has('child'));
|
||||
}
|
||||
|
||||
// The execPath might contain chars that should be escaped in a shell context.
|
||||
// On non-Windows, we can pass the path via the env; `"` is not a valid char on
|
||||
// Windows, so we can simply pass the path.
|
||||
const execNode = (args) => childProcess.execSync(
|
||||
`"${common.isWindows ? process.execPath : '$NODE'}" ${args}`,
|
||||
common.isWindows ? undefined : { env: { ...process.env, NODE: process.execPath } },
|
||||
);
|
||||
|
||||
// When a permission is set by cli, the process shouldn't be able
|
||||
// to spawn unless --allow-child-process is sent
|
||||
{
|
||||
// doesNotThrow
|
||||
childProcess.spawnSync(process.execPath, ['--version']);
|
||||
execNode('--version');
|
||||
childProcess.execSync(...common.escapePOSIXShell`"${process.execPath}" --version`);
|
||||
childProcess.fork(__filename, ['child']);
|
||||
childProcess.execFileSync(process.execPath, ['--version']);
|
||||
}
|
||||
|
@ -15,14 +15,6 @@ if (process.argv[2] === 'child') {
|
||||
assert.ok(!process.permission.has('child'));
|
||||
}
|
||||
|
||||
// The execPath might contain chars that should be escaped in a shell context.
|
||||
// On non-Windows, we can pass the path via the env; `"` is not a valid char on
|
||||
// Windows, so we can simply pass the path.
|
||||
const execNode = (args) => [
|
||||
`"${common.isWindows ? process.execPath : '$NODE'}" ${args}`,
|
||||
common.isWindows ? undefined : { env: { ...process.env, NODE: process.execPath } },
|
||||
];
|
||||
|
||||
// When a permission is set by cli, the process shouldn't be able
|
||||
// to spawn
|
||||
{
|
||||
@ -39,13 +31,13 @@ const execNode = (args) => [
|
||||
permission: 'ChildProcess',
|
||||
}));
|
||||
assert.throws(() => {
|
||||
childProcess.exec(...execNode('--version'));
|
||||
childProcess.exec(...common.escapePOSIXShell`"${process.execPath}" --version`);
|
||||
}, common.expectsError({
|
||||
code: 'ERR_ACCESS_DENIED',
|
||||
permission: 'ChildProcess',
|
||||
}));
|
||||
assert.throws(() => {
|
||||
childProcess.execSync(...execNode('--version'));
|
||||
childProcess.execSync(...common.escapePOSIXShell`"${process.execPath}" --version`);
|
||||
}, common.expectsError({
|
||||
code: 'ERR_ACCESS_DENIED',
|
||||
permission: 'ChildProcess',
|
||||
@ -57,13 +49,13 @@ const execNode = (args) => [
|
||||
permission: 'ChildProcess',
|
||||
}));
|
||||
assert.throws(() => {
|
||||
childProcess.execFile(...execNode('--version'));
|
||||
childProcess.execFile(...common.escapePOSIXShell`"${process.execPath}" --version`);
|
||||
}, common.expectsError({
|
||||
code: 'ERR_ACCESS_DENIED',
|
||||
permission: 'ChildProcess',
|
||||
}));
|
||||
assert.throws(() => {
|
||||
childProcess.execFileSync(...execNode('--version'));
|
||||
childProcess.execFileSync(...common.escapePOSIXShell`"${process.execPath}" --version`);
|
||||
}, common.expectsError({
|
||||
code: 'ERR_ACCESS_DENIED',
|
||||
permission: 'ChildProcess',
|
||||
|
@ -13,8 +13,8 @@ if (!common.isMainThread)
|
||||
const selfRefModule = fixtures.path('self_ref_module');
|
||||
const fixtureA = fixtures.path('printA.js');
|
||||
|
||||
exec(`"${nodeBinary}" -r self_ref "${fixtureA}"`, { cwd: selfRefModule },
|
||||
(err, stdout, stderr) => {
|
||||
assert.ifError(err);
|
||||
const [cmd, opts] = common.escapePOSIXShell`"${nodeBinary}" -r self_ref "${fixtureA}"`;
|
||||
exec(cmd, { ...opts, cwd: selfRefModule },
|
||||
common.mustSucceed((stdout, stderr) => {
|
||||
assert.strictEqual(stdout, 'A\n');
|
||||
});
|
||||
}));
|
||||
|
@ -7,4 +7,4 @@ const { exec } = require('child_process');
|
||||
const kNodeBinary = process.argv[0];
|
||||
|
||||
|
||||
exec(`"${kNodeBinary}" -r "${worker}" -pe "1+1"`, common.mustSucceed());
|
||||
exec(...common.escapePOSIXShell`"${kNodeBinary}" -r "${worker}" -pe "1+1"`, common.mustSucceed());
|
||||
|
@ -10,15 +10,11 @@ const stdoutScript = fixtures.path('echo-close-check.js');
|
||||
const tmpFile = tmpdir.resolve('stdin.txt');
|
||||
const string = fixtures.utf8TestText;
|
||||
|
||||
const cmd = `"${process.argv[0]}" "${stdoutScript}" < "${tmpFile}"`;
|
||||
|
||||
tmpdir.refresh();
|
||||
|
||||
console.log(`${cmd}\n\n`);
|
||||
|
||||
fs.writeFileSync(tmpFile, string);
|
||||
|
||||
childProcess.exec(cmd, common.mustCall(function(err, stdout, stderr) {
|
||||
childProcess.exec(...common.escapePOSIXShell`"${process.argv0}" "${stdoutScript}" < "${tmpFile}"`, common.mustCall(function(err, stdout, stderr) {
|
||||
fs.unlinkSync(tmpFile);
|
||||
|
||||
assert.ifError(err);
|
||||
|
@ -29,8 +29,8 @@ if (process.argv[2] === 'child') {
|
||||
}
|
||||
|
||||
// Run the script in a shell but close stdout and stderr.
|
||||
const cmd = `"${process.execPath}" "${__filename}" child 1>&- 2>&-`;
|
||||
const proc = spawn('/bin/sh', ['-c', cmd], { stdio: 'inherit' });
|
||||
const [cmd, opts] = common.escapePOSIXShell`"${process.execPath}" "${__filename}" child 1>&- 2>&-`;
|
||||
const proc = spawn('/bin/sh', ['-c', cmd], { ...opts, stdio: 'inherit' });
|
||||
|
||||
proc.on('exit', common.mustCall(function(exitCode) {
|
||||
assert.strictEqual(exitCode, 0);
|
||||
|
@ -7,12 +7,9 @@ const { getSystemErrorName } = require('util');
|
||||
|
||||
const testScript = fixtures.path('catch-stdout-error.js');
|
||||
|
||||
const cmd = `${JSON.stringify(process.execPath)} ` +
|
||||
`${JSON.stringify(testScript)} | ` +
|
||||
`${JSON.stringify(process.execPath)} ` +
|
||||
'-pe "process.stdin.on(\'data\' , () => process.exit(1))"';
|
||||
|
||||
const child = child_process.exec(cmd);
|
||||
const child = child_process.exec(
|
||||
...common.escapePOSIXShell`"${process.execPath}" "${testScript}" | "${process.execPath}" -pe "process.stdin.on('data' , () => process.exit(1))"`
|
||||
);
|
||||
let output = '';
|
||||
|
||||
child.stderr.on('data', function(c) {
|
||||
@ -21,12 +18,7 @@ child.stderr.on('data', function(c) {
|
||||
|
||||
|
||||
child.on('close', common.mustCall(function(code) {
|
||||
try {
|
||||
output = JSON.parse(output);
|
||||
} catch {
|
||||
console.error(output);
|
||||
process.exit(1);
|
||||
}
|
||||
output = JSON.parse(output);
|
||||
|
||||
assert.strictEqual(output.code, 'EPIPE');
|
||||
assert.strictEqual(getSystemErrorName(output.errno), 'EPIPE');
|
||||
|
@ -13,9 +13,6 @@ const tmpFile = tmpdir.resolve('stdout.txt');
|
||||
tmpdir.refresh();
|
||||
|
||||
function test(size, useBuffer, cb) {
|
||||
const cmd = `"${process.argv[0]}" "${
|
||||
useBuffer ? scriptBuffer : scriptString}" ${size} > "${tmpFile}"`;
|
||||
|
||||
try {
|
||||
fs.unlinkSync(tmpFile);
|
||||
} catch {
|
||||
@ -24,7 +21,9 @@ function test(size, useBuffer, cb) {
|
||||
|
||||
console.log(`${size} chars to ${tmpFile}...`);
|
||||
|
||||
childProcess.exec(cmd, common.mustSucceed(() => {
|
||||
childProcess.exec(...common.escapePOSIXShell`"${
|
||||
process.execPath}" "${useBuffer ? scriptBuffer : scriptString}" ${size} > "${tmpFile
|
||||
}"`, common.mustSucceed(() => {
|
||||
console.log('done!');
|
||||
|
||||
const stat = fs.statSync(tmpFile);
|
||||
|
@ -13,14 +13,7 @@ if (process.argv[2] === 'child') {
|
||||
);
|
||||
} else {
|
||||
const cp = require('child_process');
|
||||
cp.exec([
|
||||
'echo',
|
||||
'hello',
|
||||
'|',
|
||||
`"${process.execPath}"`,
|
||||
`"${__filename}"`,
|
||||
'child',
|
||||
].join(' '), common.mustSucceed((stdout) => {
|
||||
cp.exec(...common.escapePOSIXShell`echo hello | "${process.execPath}" "${__filename}" child`, common.mustSucceed((stdout) => {
|
||||
assert.strictEqual(stdout.split(os.EOL).shift().trim(), 'hello');
|
||||
}));
|
||||
}
|
||||
|
@ -49,10 +49,10 @@ const server = tls.createServer(options, common.mustCall(function(conn) {
|
||||
}));
|
||||
|
||||
server.listen(0, '127.0.0.1', common.mustCall(function() {
|
||||
const cmd = `"${common.opensslCli}" s_client -cipher ${
|
||||
const cmd = common.escapePOSIXShell`"${common.opensslCli}" s_client -cipher ${
|
||||
options.ciphers} -connect 127.0.0.1:${this.address().port}`;
|
||||
|
||||
exec(cmd, common.mustSucceed((stdout, stderr) => {
|
||||
exec(...cmd, common.mustSucceed((stdout, stderr) => {
|
||||
assert(stdout.includes(reply));
|
||||
server.close();
|
||||
}));
|
||||
|
@ -47,9 +47,7 @@ if (process.argv[2] === 'child') {
|
||||
|
||||
} else {
|
||||
// Limit the number of open files, to force workers to fail.
|
||||
let testCmd = `ulimit -n ${OPENFILES} && `;
|
||||
testCmd += `${process.execPath} ${__filename} child`;
|
||||
const cp = child_process.exec(testCmd);
|
||||
const cp = child_process.exec(...common.escapePOSIXShell`ulimit -n ${OPENFILES} && "${process.execPath}" "${__filename}" child`);
|
||||
|
||||
// Turn on the child streams for debugging purposes.
|
||||
let stdout = '';
|
||||
|
@ -30,12 +30,14 @@ const fs = require('fs');
|
||||
|
||||
const ulimit = Number(child_process.execSync('ulimit -Hn'));
|
||||
if (ulimit > 64 || Number.isNaN(ulimit)) {
|
||||
const [cmd, opts] = common.escapePOSIXShell`ulimit -n 64 && "${process.execPath}" "${__filename}"`;
|
||||
// Sorry about this nonsense. It can be replaced if
|
||||
// https://github.com/nodejs/node-v0.x-archive/pull/2143#issuecomment-2847886
|
||||
// ever happens.
|
||||
const result = child_process.spawnSync(
|
||||
'/bin/sh',
|
||||
['-c', `ulimit -n 64 && '${process.execPath}' '${__filename}'`]
|
||||
['-c', cmd],
|
||||
opts,
|
||||
);
|
||||
assert.strictEqual(result.stdout.toString(), '');
|
||||
assert.strictEqual(result.stderr.toString(), '');
|
||||
|
@ -1,16 +1,14 @@
|
||||
'use strict';
|
||||
|
||||
require('../common');
|
||||
const common = require('../common');
|
||||
const { exec } = require('child_process');
|
||||
const { test } = require('node:test');
|
||||
const fixtures = require('../common/fixtures');
|
||||
|
||||
const node = process.execPath;
|
||||
|
||||
// Test both sets of arguments that check syntax
|
||||
const syntaxArgs = [
|
||||
['-c'],
|
||||
['--check'],
|
||||
'-c',
|
||||
'--check',
|
||||
];
|
||||
|
||||
// Match on the name of the `Error` but not the message as it is different
|
||||
@ -27,13 +25,10 @@ const syntaxErrorRE = /^SyntaxError: \b/m;
|
||||
const path = fixtures.path(file);
|
||||
|
||||
// Loop each possible option, `-c` or `--check`
|
||||
syntaxArgs.forEach((args) => {
|
||||
test(`Checking syntax for ${file} with ${args.join(' ')}`, async (t) => {
|
||||
const _args = args.concat(path);
|
||||
const cmd = [node, ..._args].join(' ');
|
||||
|
||||
syntaxArgs.forEach((flag) => {
|
||||
test(`Checking syntax for ${file} with ${flag}`, async (t) => {
|
||||
try {
|
||||
const { stdout, stderr } = await execPromise(cmd);
|
||||
const { stdout, stderr } = await execNode(flag, path);
|
||||
|
||||
// No stdout should be produced
|
||||
t.assert.strictEqual(stdout, '');
|
||||
@ -51,9 +46,9 @@ const syntaxErrorRE = /^SyntaxError: \b/m;
|
||||
});
|
||||
|
||||
// Helper function to promisify exec
|
||||
function execPromise(cmd) {
|
||||
function execNode(flag, path) {
|
||||
const { promise, resolve, reject } = Promise.withResolvers();
|
||||
exec(cmd, (err, stdout, stderr) => {
|
||||
exec(...common.escapePOSIXShell`"${process.execPath}" ${flag} "${path}"`, (err, stdout, stderr) => {
|
||||
if (err) return reject({ ...err, stdout, stderr });
|
||||
resolve({ stdout, stderr });
|
||||
});
|
||||
|
@ -5,15 +5,6 @@ const assert = require('assert');
|
||||
const { exec } = require('child_process');
|
||||
const fixtures = require('../common/fixtures');
|
||||
|
||||
// The execPath might contain chars that should be escaped in a shell context.
|
||||
// On non-Windows, we can pass the path via the env; `"` is not a valid char on
|
||||
// Windows, so we can simply pass the path.
|
||||
const execNode = (flag, file, callback) => exec(
|
||||
`"${common.isWindows ? process.execPath : '$NODE'}" ${flag} "${common.isWindows ? file : '$FILE'}"`,
|
||||
common.isWindows ? undefined : { env: { ...process.env, NODE: process.execPath, FILE: file } },
|
||||
callback,
|
||||
);
|
||||
|
||||
// Test both sets of arguments that check syntax
|
||||
const syntaxArgs = [
|
||||
'-c',
|
||||
@ -31,7 +22,7 @@ const notFoundRE = /^Error: Cannot find module/m;
|
||||
|
||||
// Loop each possible option, `-c` or `--check`
|
||||
syntaxArgs.forEach(function(flag) {
|
||||
execNode(flag, file, common.mustCall((err, stdout, stderr) => {
|
||||
exec(...common.escapePOSIXShell`"${process.execPath}" ${flag} "${file}"`, common.mustCall((err, stdout, stderr) => {
|
||||
// No stdout should be produced
|
||||
assert.strictEqual(stdout, '');
|
||||
|
||||
|
@ -5,15 +5,6 @@ const assert = require('assert');
|
||||
const { exec } = require('child_process');
|
||||
const fixtures = require('../common/fixtures');
|
||||
|
||||
// The execPath might contain chars that should be escaped in a shell context.
|
||||
// On non-Windows, we can pass the path via the env; `"` is not a valid char on
|
||||
// Windows, so we can simply pass the path.
|
||||
const execNode = (flag, file, callback) => exec(
|
||||
`"${common.isWindows ? process.execPath : '$NODE'}" ${flag} "${common.isWindows ? file : '$FILE'}"`,
|
||||
common.isWindows ? undefined : { env: { ...process.env, NODE: process.execPath, FILE: file } },
|
||||
callback,
|
||||
);
|
||||
|
||||
// Test both sets of arguments that check syntax
|
||||
const syntaxArgs = [
|
||||
'-c',
|
||||
@ -33,7 +24,7 @@ const syntaxArgs = [
|
||||
|
||||
// Loop each possible option, `-c` or `--check`
|
||||
syntaxArgs.forEach(function(flag) {
|
||||
execNode(flag, file, common.mustCall((err, stdout, stderr) => {
|
||||
exec(...common.escapePOSIXShell`"${process.execPath}" ${flag} "${file}"`, common.mustCall((err, stdout, stderr) => {
|
||||
if (err) {
|
||||
console.log('-- stdout --');
|
||||
console.log(stdout);
|
||||
|
@ -35,8 +35,7 @@ if (process.env.TEST_INIT) {
|
||||
process.env.TEST_INIT = 1;
|
||||
|
||||
function test(file, expected) {
|
||||
const path = `"${process.execPath}" ${file}`;
|
||||
child.exec(path, { env: process.env }, common.mustSucceed((out) => {
|
||||
child.exec(...common.escapePOSIXShell`"${process.execPath}" "${file}"`, common.mustSucceed((out) => {
|
||||
assert.strictEqual(out, expected, `'node ${file}' failed!`);
|
||||
}));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user