Skip to content

Commit 80fc01c

Browse files
SirR4Ttargos
authored andcommitted
child_process: allow typed arrays for input
doc: Update child_process docs, stating typed arrays are allowed. error: Update error message for `ERR_INVALID_SYNC_FORK_INPUT` lib: Use isArrayBufferView instead of isUint8Array test: Update test-child-process-spawnsync-input to test for all typed arrays and data view. PR-URL: #22409 Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Trivikram Kamat <[email protected]>
1 parent 7ce8a98 commit 80fc01c

File tree

6 files changed

+46
-22
lines changed

6 files changed

+46
-22
lines changed

doc/api/child_process.md

+21-6
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,10 @@ configuration at startup.
679679
<!-- YAML
680680
added: v0.11.12
681681
changes:
682+
- version: REPLACEME
683+
pr-url: https://github.com/nodejs/node/pull/22409
684+
description: The `input` option can now be any `TypedArray` or a
685+
`DataView`.
682686
- version: v8.8.0
683687
pr-url: https://github.com/nodejs/node/pull/15380
684688
description: The `windowsHide` option is supported now.
@@ -694,8 +698,9 @@ changes:
694698
* `args` {string[]} List of string arguments.
695699
* `options` {Object}
696700
* `cwd` {string} Current working directory of the child process.
697-
* `input` {string|Buffer|Uint8Array} The value which will be passed as stdin
698-
to the spawned process. Supplying this value will override `stdio[0]`.
701+
* `input` {string|Buffer|TypedArray|DataView} The value which will be passed
702+
as stdin to the spawned process. Supplying this value will override
703+
`stdio[0]`.
699704
* `stdio` {string|Array} Child's stdio configuration. `stderr` by default will
700705
be output to the parent process' stderr unless `stdio` is specified.
701706
**Default:** `'pipe'`.
@@ -741,6 +746,10 @@ arbitrary command execution.**
741746
<!-- YAML
742747
added: v0.11.12
743748
changes:
749+
- version: REPLACEME
750+
pr-url: https://github.com/nodejs/node/pull/22409
751+
description: The `input` option can now be any `TypedArray` or a
752+
`DataView`.
744753
- version: v8.8.0
745754
pr-url: https://github.com/nodejs/node/pull/15380
746755
description: The `windowsHide` option is supported now.
@@ -752,8 +761,9 @@ changes:
752761
* `command` {string} The command to run.
753762
* `options` {Object}
754763
* `cwd` {string} Current working directory of the child process.
755-
* `input` {string|Buffer|Uint8Array} The value which will be passed as stdin
756-
to the spawned process. Supplying this value will override `stdio[0]`.
764+
* `input` {string|Buffer|TypedArray|DataView} The value which will be passed
765+
as stdin to the spawned process. Supplying this value will override
766+
`stdio[0]`.
757767
* `stdio` {string|Array} Child's stdio configuration. `stderr` by default will
758768
be output to the parent process' stderr unless `stdio` is specified.
759769
**Default:** `'pipe'`.
@@ -795,6 +805,10 @@ metacharacters may be used to trigger arbitrary command execution.**
795805
<!-- YAML
796806
added: v0.11.12
797807
changes:
808+
- version: REPLACEME
809+
pr-url: https://github.com/nodejs/node/pull/22409
810+
description: The `input` option can now be any `TypedArray` or a
811+
`DataView`.
798812
- version: v8.8.0
799813
pr-url: https://github.com/nodejs/node/pull/15380
800814
description: The `windowsHide` option is supported now.
@@ -813,8 +827,9 @@ changes:
813827
* `args` {string[]} List of string arguments.
814828
* `options` {Object}
815829
* `cwd` {string} Current working directory of the child process.
816-
* `input` {string|Buffer|Uint8Array} The value which will be passed as stdin
817-
to the spawned process. Supplying this value will override `stdio[0]`.
830+
* `input` {string|Buffer|TypedArray|DataView} The value which will be passed
831+
as stdin to the spawned process. Supplying this value will override
832+
`stdio[0]`.
818833
* `argv0` {string} Explicitly set the value of `argv[0]` sent to the child
819834
process. This will be set to `command` if not specified.
820835
* `stdio` {string|Array} Child's stdio configuration.

doc/api/errors.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -1259,8 +1259,8 @@ For example when a function is expected to return a promise.
12591259
<a id="ERR_INVALID_SYNC_FORK_INPUT"></a>
12601260
### ERR_INVALID_SYNC_FORK_INPUT
12611261

1262-
A `Buffer`, `Uint8Array` or `string` was provided as stdio input to a
1263-
synchronous fork. See the documentation for the [`child_process`][] module
1262+
A `Buffer`, `TypedArray`, `DataView` or `string` was provided as stdio input to
1263+
an asynchronous fork. See the documentation for the [`child_process`][] module
12641264
for more information.
12651265

12661266
<a id="ERR_INVALID_THIS"></a>

lib/child_process.js

+6-3
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ const util = require('util');
2525
const {
2626
deprecate, convertToValidSignal, getSystemErrorName
2727
} = require('internal/util');
28-
const { isUint8Array } = require('internal/util/types');
28+
const { isArrayBufferView } = require('internal/util/types');
2929
const debug = util.debuglog('child_process');
3030
const { Buffer } = require('buffer');
3131
const { Pipe, constants: PipeConstants } = process.binding('pipe_wrap');
@@ -570,13 +570,16 @@ function spawnSync(/* file, args, options */) {
570570
var input = options.stdio[i] && options.stdio[i].input;
571571
if (input != null) {
572572
var pipe = options.stdio[i] = util._extend({}, options.stdio[i]);
573-
if (isUint8Array(input)) {
573+
if (isArrayBufferView(input)) {
574574
pipe.input = input;
575575
} else if (typeof input === 'string') {
576576
pipe.input = Buffer.from(input, options.encoding);
577577
} else {
578578
throw new ERR_INVALID_ARG_TYPE(`options.stdio[${i}]`,
579-
['Buffer', 'Uint8Array', 'string'],
579+
['Buffer',
580+
'TypedArray',
581+
'DataView',
582+
'string'],
580583
input);
581584
}
582585
}

lib/internal/child_process.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ const { UDP } = process.binding('udp_wrap');
3030
const SocketList = require('internal/socket_list');
3131
const { owner_symbol } = require('internal/async_hooks').symbols;
3232
const { convertToValidSignal } = require('internal/util');
33-
const { isUint8Array } = require('internal/util/types');
33+
const { isArrayBufferView } = require('internal/util/types');
3434
const spawn_sync = process.binding('spawn_sync');
3535
const { HTTPParser } = process.binding('http_parser');
3636
const { freeParser } = require('_http_common');
@@ -926,7 +926,7 @@ function _validateStdio(stdio, sync) {
926926
wrapType: getHandleWrapType(handle),
927927
handle: handle
928928
});
929-
} else if (isUint8Array(stdio) || typeof stdio === 'string') {
929+
} else if (isArrayBufferView(stdio) || typeof stdio === 'string') {
930930
if (!sync) {
931931
cleanup();
932932
throw new ERR_INVALID_SYNC_FORK_INPUT(util.inspect(stdio));

lib/internal/errors.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -719,7 +719,8 @@ E('ERR_INVALID_RETURN_VALUE', (input, name, value) => {
719719
` function but got ${type}.`;
720720
}, TypeError);
721721
E('ERR_INVALID_SYNC_FORK_INPUT',
722-
'Asynchronous forks do not support Buffer, Uint8Array or string input: %s',
722+
'Asynchronous forks do not support ' +
723+
'Buffer, TypedArray, DataView or string input: %s',
723724
TypeError);
724725
E('ERR_INVALID_THIS', 'Value of "this" must be of type %s', TypeError);
725726
E('ERR_INVALID_TUPLE', '%s must be an iterable %s tuple', TypeError);

test/parallel/test-child-process-spawnsync-input.js

+13-8
Original file line numberDiff line numberDiff line change
@@ -100,16 +100,21 @@ checkSpawnSyncRet(ret);
100100
assert.deepStrictEqual(ret.stdout, options.input);
101101
assert.deepStrictEqual(ret.stderr, Buffer.from(''));
102102

103-
options = {
104-
input: Uint8Array.from(Buffer.from('hello world'))
105-
};
103+
// common.getArrayBufferViews expects a buffer
104+
// with length an multiple of 8
105+
const msgBuf = Buffer.from('hello world'.repeat(8));
106+
for (const arrayBufferView of common.getArrayBufferViews(msgBuf)) {
107+
options = {
108+
input: arrayBufferView
109+
};
106110

107-
ret = spawnSync('cat', [], options);
111+
ret = spawnSync('cat', [], options);
108112

109-
checkSpawnSyncRet(ret);
110-
// Wrap options.input because Uint8Array and Buffer have different prototypes.
111-
assert.deepStrictEqual(ret.stdout, Buffer.from(options.input));
112-
assert.deepStrictEqual(ret.stderr, Buffer.from(''));
113+
checkSpawnSyncRet(ret);
114+
115+
assert.deepStrictEqual(ret.stdout, msgBuf);
116+
assert.deepStrictEqual(ret.stderr, Buffer.from(''));
117+
}
113118

114119
verifyBufOutput(spawnSync(process.execPath, args));
115120

0 commit comments

Comments
 (0)