Skip to content

Commit 4ca3f67

Browse files
committed
child_process: validate exec's options.shell as string
1 parent 6a46f31 commit 4ca3f67

File tree

3 files changed

+29
-8
lines changed

3 files changed

+29
-8
lines changed

lib/child_process.js

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,13 @@ function normalizeExecArgs(command, options, callback) {
199199

200200
// Make a shallow copy so we don't clobber the user's options object.
201201
options = { __proto__: null, ...options };
202-
options.shell = typeof options.shell === 'string' ? options.shell : true;
202+
203+
// Validate the shell, if present, otherwise request the default shell.
204+
if (options.shell != null && options.shell !== true) {
205+
validateString(options.shell, 'options.shell');
206+
} else {
207+
options.shell = true;
208+
}
203209

204210
return {
205211
file: command,
@@ -613,11 +619,12 @@ function normalizeSpawnArguments(file, args, options) {
613619
}
614620

615621
// Validate the shell, if present.
616-
if (options.shell != null &&
617-
typeof options.shell !== 'boolean' &&
618-
typeof options.shell !== 'string') {
619-
throw new ERR_INVALID_ARG_TYPE('options.shell',
620-
['boolean', 'string'], options.shell);
622+
if (options.shell != null) {
623+
if (typeof options.shell !== 'boolean' && typeof options.shell !== 'string') {
624+
throw new ERR_INVALID_ARG_TYPE('options.shell',
625+
['boolean', 'string'], options.shell);
626+
}
627+
validateArgumentNullCheck(options.shell, 'options.shell');
621628
}
622629

623630
// Validate argv0, if present.
@@ -639,7 +646,6 @@ function normalizeSpawnArguments(file, args, options) {
639646
}
640647

641648
if (options.shell) {
642-
validateArgumentNullCheck(options.shell, 'options.shell');
643649
if (args.length > 0 && !emittedDEP0190Already) {
644650
process.emitWarning(
645651
'Passing args to a child process with shell option true can lead to security ' +

test/parallel/test-child-process-exec-any-shells-windows.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ const testCopy = (shellName, shellPath) => {
3333
const system32 = `${process.env.SystemRoot}\\System32`;
3434

3535
// Test CMD
36-
test(true);
36+
test(null);
3737
test('cmd');
3838
testCopy('cmd.exe', `${system32}\\cmd.exe`);
3939
test('cmd.exe');
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
'use strict';
2+
require('../common');
3+
const assert = require('assert');
4+
const { exec, execSync } = require('child_process');
5+
6+
const invalidArgTypeError = {
7+
code: 'ERR_INVALID_ARG_TYPE',
8+
name: 'TypeError'
9+
};
10+
11+
for (const fn of [exec, execSync]) {
12+
assert.throws(() => fn('should-throw-on-boolean-shell-option', { shell: false }), invalidArgTypeError);
13+
}
14+
15+
// TODO: add DEP0196 tests following runtime deprecation

0 commit comments

Comments
 (0)