Skip to content

Commit 7b2eefc

Browse files
eduardbmeMylesBorins
authored andcommitted
child_process: spawn ignores options in case args is undefined
spawn method ignores 3-d argument 'options' in case the second one 'args' equals to 'undefined'. Fixes: #24912 PR-URL: #24913 Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com>
1 parent 96bdd47 commit 7b2eefc

4 files changed

Lines changed: 103 additions & 8 deletions

File tree

‎lib/child_process.js‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -403,8 +403,9 @@ function normalizeSpawnArguments(file, args, options) {
403403

404404
if(Array.isArray(args)){
405405
args=args.slice(0);
406-
}elseif(args!==undefined&&
407-
(args===null||typeofargs!=='object')){
406+
}elseif(args==null){
407+
args=[];
408+
}elseif(typeofargs!=='object'){
408409
thrownewERR_INVALID_ARG_TYPE('args','object',args);
409410
}else{
410411
options=args;
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
'use strict';
2+
3+
// This test confirms that `undefined`, `null`, and `[]`
4+
// can be used as a placeholder for the second argument (`args`) of `spawn()`.
5+
// Previously, there was a bug where using `undefined` for the second argument
6+
// caused the third argument (`options`) to be ignored.
7+
// See https://github.com/nodejs/node/issues/24912.
8+
9+
constassert=require('assert');
10+
const{ spawn }=require('child_process');
11+
12+
constcommon=require('../common');
13+
consttmpdir=require('../common/tmpdir');
14+
15+
constcommand=common.isWindows ? 'cd' : 'pwd';
16+
constoptions={cwd: tmpdir.path};
17+
18+
if(common.isWindows){
19+
// This test is not the case for Windows based systems
20+
// unless the `shell` options equals to `true`
21+
22+
options.shell=true;
23+
}
24+
25+
consttestCases=[
26+
undefined,
27+
null,
28+
[],
29+
];
30+
31+
constexpectedResult=tmpdir.path.trim().toLowerCase();
32+
33+
(async()=>{
34+
constresults=awaitPromise.all(
35+
testCases.map((testCase)=>{
36+
returnnewPromise((resolve)=>{
37+
constsubprocess=spawn(command,testCase,options);
38+
39+
letaccumulatedData=Buffer.alloc(0);
40+
41+
subprocess.stdout.on('data',common.mustCall((data)=>{
42+
accumulatedData=Buffer.concat([accumulatedData,data]);
43+
}));
44+
45+
subprocess.stdout.on('end',()=>{
46+
resolve(accumulatedData.toString().trim().toLowerCase());
47+
});
48+
});
49+
})
50+
);
51+
52+
assert.deepStrictEqual([...newSet(results)],[expectedResult]);
53+
})();

‎test/parallel/test-child-process-spawn-typeerror.js‎

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ const invalidArgValueError =
3333
common.expectsError({code: 'ERR_INVALID_ARG_VALUE',type: TypeError},14);
3434

3535
constinvalidArgTypeError=
36-
common.expectsError({code: 'ERR_INVALID_ARG_TYPE',type: TypeError},13);
36+
common.expectsError({code: 'ERR_INVALID_ARG_TYPE',type: TypeError},11);
3737

3838
assert.throws(function(){
3939
spawn(invalidcmd,'this is not an array');
@@ -59,10 +59,6 @@ assert.throws(function() {
5959
spawn(file);
6060
},invalidArgTypeError);
6161

62-
assert.throws(function(){
63-
spawn(cmd,null);
64-
},invalidArgTypeError);
65-
6662
assert.throws(function(){
6763
spawn(cmd,true);
6864
},invalidArgTypeError);
@@ -103,9 +99,9 @@ spawn(cmd, o);
10399

104100
// Variants of undefined as explicit 'no argument' at a position.
105101
spawn(cmd,u,o);
102+
spawn(cmd,n,o);
106103
spawn(cmd,a,u);
107104

108-
assert.throws(function(){spawn(cmd,n,o);},invalidArgTypeError);
109105
assert.throws(function(){spawn(cmd,a,n);},invalidArgTypeError);
110106

111107
assert.throws(function(){spawn(cmd,s);},invalidArgTypeError);
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
'use strict';
2+
3+
// This test confirms that `undefined`, `null`, and `[]` can be used
4+
// as a placeholder for the second argument (`args`) of `spawnSync()`.
5+
// Previously, there was a bug where using `undefined` for the second argument
6+
// caused the third argument (`options`) to be ignored.
7+
// See https://github.com/nodejs/node/issues/24912.
8+
9+
constassert=require('assert');
10+
const{ spawnSync }=require('child_process');
11+
12+
constcommon=require('../common');
13+
consttmpdir=require('../common/tmpdir');
14+
15+
constcommand=common.isWindows ? 'cd' : 'pwd';
16+
constoptions={cwd: tmpdir.path};
17+
18+
if(common.isWindows){
19+
// This test is not the case for Windows based systems
20+
// unless the `shell` options equals to `true`
21+
22+
options.shell=true;
23+
}
24+
25+
consttestCases=[
26+
undefined,
27+
null,
28+
[],
29+
];
30+
31+
constexpectedResult=tmpdir.path.trim().toLowerCase();
32+
33+
constresults=testCases.map((testCase)=>{
34+
const{ stdout, stderr }=spawnSync(
35+
command,
36+
testCase,
37+
options
38+
);
39+
40+
assert.deepStrictEqual(stderr,Buffer.alloc(0));
41+
42+
returnstdout.toString().trim().toLowerCase();
43+
});
44+
45+
assert.deepStrictEqual([...newSet(results)],[expectedResult]);

0 commit comments

Comments
 (0)