From 5d5621929026bf190a426fb7e118508be95c21d1 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Fri, 6 Jan 2017 02:12:26 +0100 Subject: [PATCH] child_process: support Uint8Array input to methods Support `Uint8Array` input to all the synchronous methods. --- doc/api/child_process.md | 12 ++++++------ lib/child_process.js | 5 +++-- lib/internal/child_process.js | 7 ++++--- test/parallel/test-child-process-spawnsync-input.js | 12 +++++++++++- 4 files changed, 24 insertions(+), 12 deletions(-) diff --git a/doc/api/child_process.md b/doc/api/child_process.md index f735376134025a..72373fcadd7453 100644 --- a/doc/api/child_process.md +++ b/doc/api/child_process.md @@ -580,8 +580,8 @@ added: v0.11.12 * `args` {Array} List of string arguments * `options` {Object} * `cwd` {String} Current working directory of the child process - * `input` {String|Buffer} The value which will be passed as stdin to the - spawned process + * `input` {String|Buffer|Uint8Array} The value which will be passed as stdin + to the spawned process - supplying this value will override `stdio[0]` * `stdio` {String | Array} Child's stdio configuration. (Default: `'pipe'`) - `stderr` by default will be output to the parent process' stderr unless @@ -618,8 +618,8 @@ added: v0.11.12 * `command` {String} The command to run * `options` {Object} * `cwd` {String} Current working directory of the child process - * `input` {String|Buffer} The value which will be passed as stdin to the - spawned process + * `input` {String|Buffer|Uint8Array} The value which will be passed as stdin + to the spawned process - supplying this value will override `stdio[0]` * `stdio` {String | Array} Child's stdio configuration. (Default: `'pipe'`) - `stderr` by default will be output to the parent process' stderr unless @@ -666,8 +666,8 @@ added: v0.11.12 * `args` {Array} List of string arguments * `options` {Object} * `cwd` {String} Current working directory of the child process - * `input` {String|Buffer} The value which will be passed as stdin to the - spawned process + * `input` {String|Buffer|Uint8Array} The value which will be passed as stdin + to the spawned process - supplying this value will override `stdio[0]` * `stdio` {String | Array} Child's stdio configuration. * `env` {Object} Environment key-value pairs diff --git a/lib/child_process.js b/lib/child_process.js index 03956a999e1141..6fe5351fd6fdda 100644 --- a/lib/child_process.js +++ b/lib/child_process.js @@ -9,6 +9,7 @@ const uv = process.binding('uv'); const spawn_sync = process.binding('spawn_sync'); const Buffer = require('buffer').Buffer; const Pipe = process.binding('pipe_wrap').Pipe; +const { isUint8Array } = process.binding('util'); const child_process = require('internal/child_process'); const errnoException = util._errnoException; @@ -503,13 +504,13 @@ function spawnSync(/*file, args, options*/) { var input = options.stdio[i] && options.stdio[i].input; if (input != null) { var pipe = options.stdio[i] = util._extend({}, options.stdio[i]); - if (Buffer.isBuffer(input)) + if (isUint8Array(input)) pipe.input = input; else if (typeof input === 'string') pipe.input = Buffer.from(input, options.encoding); else throw new TypeError(util.format( - 'stdio[%d] should be Buffer or string not %s', + 'stdio[%d] should be Buffer, Uint8Array or string not %s', i, typeof input)); } diff --git a/lib/internal/child_process.js b/lib/internal/child_process.js index 5bdc53fd192073..16ebc475f5fa53 100644 --- a/lib/internal/child_process.js +++ b/lib/internal/child_process.js @@ -1,7 +1,6 @@ 'use strict'; const StringDecoder = require('string_decoder').StringDecoder; -const Buffer = require('buffer').Buffer; const EventEmitter = require('events'); const net = require('net'); const dgram = require('dgram'); @@ -17,6 +16,7 @@ const TTY = process.binding('tty_wrap').TTY; const TCP = process.binding('tcp_wrap').TCP; const UDP = process.binding('udp_wrap').UDP; const SocketList = require('internal/socket_list'); +const { isUint8Array } = process.binding('util'); const errnoException = util._errnoException; const SocketListSend = SocketList.SocketListSend; @@ -847,10 +847,11 @@ function _validateStdio(stdio, sync) { wrapType: getHandleWrapType(handle), handle: handle }); - } else if (stdio instanceof Buffer || typeof stdio === 'string') { + } else if (isUint8Array(stdio) || typeof stdio === 'string') { if (!sync) { cleanup(); - throw new TypeError('Asynchronous forks do not support Buffer input: ' + + throw new TypeError('Asynchronous forks do not support ' + + 'Buffer, Uint8Array or string input: ' + util.inspect(stdio)); } } else { diff --git a/test/parallel/test-child-process-spawnsync-input.js b/test/parallel/test-child-process-spawnsync-input.js index fdd29aa7d0cc50..8c0464facd552b 100644 --- a/test/parallel/test-child-process-spawnsync-input.js +++ b/test/parallel/test-child-process-spawnsync-input.js @@ -57,7 +57,7 @@ var options = { assert.throws(function() { spawnSync('cat', [], options); -}, /TypeError:.*should be Buffer or string not number/); +}, /TypeError:.*should be Buffer, Uint8Array or string not number/); options = { @@ -80,6 +80,16 @@ checkSpawnSyncRet(ret); assert.deepStrictEqual(ret.stdout, options.input); assert.deepStrictEqual(ret.stderr, Buffer.from('')); +options = { + input: Uint8Array.from(Buffer.from('hello world')) +}; + +ret = spawnSync('cat', [], options); + +checkSpawnSyncRet(ret); +assert.deepStrictEqual(ret.stdout, options.input); +assert.deepStrictEqual(ret.stderr, Buffer.from('')); + verifyBufOutput(spawnSync(process.execPath, args)); ret = spawnSync(process.execPath, args, { encoding: 'utf8' });