Skip to content

Commit 54447d9

Browse files
committed
child_process: avoid repeated calls to normalizeSpawnArguments
1 parent 797e41c commit 54447d9

File tree

2 files changed

+58
-26
lines changed

2 files changed

+58
-26
lines changed

lib/child_process.js

Lines changed: 45 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,40 @@ ObjectDefineProperty(exec, promisify.custom, {
248248
value: customPromiseExecFunction(exec)
249249
});
250250

251+
function normalizeExecFileArgs(file, args, options, callback) {
252+
if (ArrayIsArray(args)) {
253+
args = ArrayPrototypeSlice(args)
254+
} else if (args != null && typeof args === 'object') {
255+
callback = options;
256+
options = args;
257+
args = null;
258+
} else if (typeof args === 'function') {
259+
callback = args;
260+
options = null;
261+
args = null;
262+
}
263+
264+
if (args == null) {
265+
args = [];
266+
}
267+
268+
if (typeof options === 'function') {
269+
callback = options;
270+
} else if (options != null) {
271+
validateObject(options, 'options');
272+
}
273+
274+
if (options == null) {
275+
options = {};
276+
}
277+
278+
if (callback != null) {
279+
validateFunction(callback, 'callback');
280+
}
281+
282+
return [file, args, options, callback];
283+
}
284+
251285
/**
252286
* Spawns the specified file as a shell.
253287
* @param {string} file
@@ -274,26 +308,7 @@ ObjectDefineProperty(exec, promisify.custom, {
274308
* @returns {ChildProcess}
275309
*/
276310
function execFile(file, args = [], options, callback) {
277-
if (args != null && typeof args === 'object' && !ArrayIsArray(args)) {
278-
callback = options;
279-
options = args;
280-
args = null;
281-
} else if (typeof args === 'function') {
282-
callback = args;
283-
options = null;
284-
args = null;
285-
}
286-
287-
if (typeof options === 'function') {
288-
callback = options;
289-
options = null;
290-
} else if (options != null) {
291-
validateObject(options, 'options');
292-
}
293-
294-
if (callback != null) {
295-
validateFunction(callback, 'callback');
296-
}
311+
[file, args, options, callback] = normalizeExecFileArgs(file, args, options, callback);
297312

298313
options = {
299314
encoding: 'utf8',
@@ -841,17 +856,22 @@ function checkExecSyncError(ret, args, cmd) {
841856
* }} [options]
842857
* @returns {Buffer | string}
843858
*/
844-
function execFileSync(command, args, options) {
845-
options = normalizeSpawnArguments(command, args, options);
859+
function execFileSync(file, args, options) {
860+
[file, args, options] = normalizeExecFileArgs(file, args, options);
846861

847862
const inheritStderr = !options.stdio;
848-
const ret = spawnSync(options.file,
849-
ArrayPrototypeSlice(options.args, 1), options);
863+
const ret = spawnSync(file, args, options);
850864

851865
if (inheritStderr && ret.stderr)
852866
process.stderr.write(ret.stderr);
853867

854-
const err = checkExecSyncError(ret, options.args, undefined);
868+
if (typeof options.argv0 === 'string') {
869+
ArrayPrototypeUnshift(args, options.argv0);
870+
} else {
871+
ArrayPrototypeUnshift(args, file);
872+
}
873+
874+
const err = checkExecSyncError(ret, args);
855875

856876
if (err)
857877
throw err;

test/parallel/test-child-process-execfile.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
const common = require('../common');
44
const assert = require('assert');
5-
const execFile = require('child_process').execFile;
5+
const { execFile, execFileSync } = require('child_process');
66
const { getEventListeners } = require('events');
77
const { getSystemErrorName } = require('util');
88
const fixtures = require('../common/fixtures');
@@ -99,3 +99,15 @@ const execOpts = { encoding: 'utf8', shell: true };
9999
});
100100
execFile(process.execPath, [fixture, 0], { signal }, callback);
101101
}
102+
103+
// Verify the execFile() stdout is the same as execFileSync().
104+
{
105+
const execArgs = ['echo', ['foo', 'bar'], { shell: true, encoding: 'utf8' }];
106+
const execFileSyncResult = execFileSync(...execArgs);
107+
assert.strictEqual(execFileSyncResult.trim(), execArgs[1].join(' '));
108+
109+
const check = common.mustCall((_, stdout) => {
110+
assert.strictEqual(stdout, execFileSyncResult);
111+
});
112+
execFile(...execArgs, check);
113+
}

0 commit comments

Comments
 (0)