doc: fix default maxBuffer size

Correctly document the default maxBuffer size for execSync,
execFileSync, and spawnSync. It is 200 * 1024, not Infinity.
Add tests to verify behaviour is as documented.

PR-URL: https://github.com/nodejs/node/pull/22894
Reviewed-By: Sam Roberts <vieuxtech@gmail.com>
This commit is contained in:
kohta ito 2018-09-17 18:19:26 +09:00 committed by Sam Roberts
parent b180a15727
commit ceb80f4157
6 changed files with 211 additions and 3 deletions

View File

@ -721,7 +721,7 @@ changes:
process will be killed. **Default:** `'SIGTERM'`. process will be killed. **Default:** `'SIGTERM'`.
* `maxBuffer` {number} Largest amount of data in bytes allowed on stdout or * `maxBuffer` {number} Largest amount of data in bytes allowed on stdout or
stderr. If exceeded, the child process is terminated. See caveat at stderr. If exceeded, the child process is terminated. See caveat at
[`maxBuffer` and Unicode][]. **Default:** `200 * 1024`. [`maxBuffer` and Unicode][]. **Default:** `Infinity`.
* `encoding` {string} The encoding used for all stdio inputs and outputs. * `encoding` {string} The encoding used for all stdio inputs and outputs.
**Default:** `'buffer'`. **Default:** `'buffer'`.
* `windowsHide` {boolean} Hide the subprocess console window that would * `windowsHide` {boolean} Hide the subprocess console window that would
@ -788,7 +788,7 @@ changes:
* `maxBuffer` {number} Largest amount of data in bytes allowed on stdout or * `maxBuffer` {number} Largest amount of data in bytes allowed on stdout or
stderr. If exceeded, the child process is terminated and any output is stderr. If exceeded, the child process is terminated and any output is
truncated. See caveat at [`maxBuffer` and Unicode][]. truncated. See caveat at [`maxBuffer` and Unicode][].
**Default:** `200 * 1024`. **Default:** `Infinity`.
* `encoding` {string} The encoding used for all stdio inputs and outputs. * `encoding` {string} The encoding used for all stdio inputs and outputs.
**Default:** `'buffer'`. **Default:** `'buffer'`.
* `windowsHide` {boolean} Hide the subprocess console window that would * `windowsHide` {boolean} Hide the subprocess console window that would
@ -852,7 +852,7 @@ changes:
* `maxBuffer` {number} Largest amount of data in bytes allowed on stdout or * `maxBuffer` {number} Largest amount of data in bytes allowed on stdout or
stderr. If exceeded, the child process is terminated and any output is stderr. If exceeded, the child process is terminated and any output is
truncated. See caveat at [`maxBuffer` and Unicode][]. truncated. See caveat at [`maxBuffer` and Unicode][].
**Default:** `200 * 1024`. **Default:** `Infinity`.
* `encoding` {string} The encoding used for all stdio inputs and outputs. * `encoding` {string} The encoding used for all stdio inputs and outputs.
**Default:** `'buffer'`. **Default:** `'buffer'`.
* `shell` {boolean|string} If `true`, runs `command` inside of a shell. Uses * `shell` {boolean|string} If `true`, runs `command` inside of a shell. Uses

View File

@ -10,6 +10,29 @@ function runChecks(err, stdio, streamName, expected) {
assert.deepStrictEqual(stdio[streamName], expected); assert.deepStrictEqual(stdio[streamName], expected);
} }
// default value
{
const cmd = `"${process.execPath}" -e "console.log('a'.repeat(200 * 1024))"`;
cp.exec(cmd, common.mustCall((err) => {
assert(err instanceof RangeError);
assert.strictEqual(err.message, 'stdout maxBuffer length exceeded');
assert.strictEqual(err.code, 'ERR_CHILD_PROCESS_STDIO_MAXBUFFER');
}));
}
// default value
{
const cmd =
`${process.execPath} -e "console.log('a'.repeat(200 * 1024 - 1))"`;
cp.exec(cmd, common.mustCall((err, stdout, stderr) => {
assert.ifError(err);
assert.strictEqual(stdout.trim(), 'a'.repeat(200 * 1024 - 1));
assert.strictEqual(stderr, '');
}));
}
{ {
const cmd = `"${process.execPath}" -e "console.log('hello world');"`; const cmd = `"${process.execPath}" -e "console.log('hello world');"`;
const options = { maxBuffer: Infinity }; const options = { maxBuffer: Infinity };

View File

@ -0,0 +1,94 @@
'use strict';
const common = require('../common');
const assert = require('assert');
const { execFile } = require('child_process');
function checkFactory(streamName) {
return common.mustCall((err) => {
assert(err instanceof RangeError);
assert.strictEqual(err.message, `${streamName} maxBuffer length exceeded`);
assert.strictEqual(err.code, 'ERR_CHILD_PROCESS_STDIO_MAXBUFFER');
});
}
// default value
{
execFile(
process.execPath,
['-e', 'console.log("a".repeat(200 * 1024))'],
checkFactory('stdout')
);
}
// default value
{
execFile(
process.execPath,
['-e', 'console.log("a".repeat(200 * 1024 - 1))'],
common.mustCall((err, stdout, stderr) => {
assert.ifError(err);
assert.strictEqual(stdout.trim(), 'a'.repeat(200 * 1024 - 1));
assert.strictEqual(stderr, '');
})
);
}
{
const options = { maxBuffer: Infinity };
execFile(
process.execPath,
['-e', 'console.log("hello world");'],
options,
common.mustCall((err, stdout, stderr) => {
assert.ifError(err);
assert.strictEqual(stdout.trim(), 'hello world');
assert.strictEqual(stderr, '');
})
);
}
{
execFile('echo', ['hello world'], { maxBuffer: 5 }, checkFactory('stdout'));
}
const unicode = '中文测试'; // length = 4, byte length = 12
{
execFile(
process.execPath,
['-e', `console.log('${unicode}');`],
{ maxBuffer: 10 },
checkFactory('stdout'));
}
{
execFile(
process.execPath,
['-e', `console.error('${unicode}');`],
{ maxBuffer: 10 },
checkFactory('stderr')
);
}
{
const child = execFile(
process.execPath,
['-e', `console.log('${unicode}');`],
{ encoding: null, maxBuffer: 10 },
checkFactory('stdout')
);
child.stdout.setEncoding('utf-8');
}
{
const child = execFile(
process.execPath,
['-e', `console.error('${unicode}');`],
{ encoding: null, maxBuffer: 10 },
checkFactory('stderr')
);
child.stderr.setEncoding('utf-8');
}

View File

@ -0,0 +1,46 @@
'use strict';
require('../common');
// This test checks that the maxBuffer option for child_process.spawnSync()
// works as expected.
const assert = require('assert');
const execFileSync = require('child_process').execFileSync;
const msgOut = 'this is stdout';
const msgOutBuf = Buffer.from(`${msgOut}\n`);
const args = [
'-e',
`console.log("${msgOut}");`
];
// Verify that an error is returned if maxBuffer is surpassed.
{
assert.throws(
() => execFileSync(process.execPath, args, { maxBuffer: 1 }),
(e) => {
assert.ok(e, 'maxBuffer should error');
assert.strictEqual(e.errno, 'ENOBUFS');
assert.deepStrictEqual(e.stdout, msgOutBuf);
return true;
}
);
}
// Verify that a maxBuffer size of Infinity works.
{
const ret = execFileSync(process.execPath, args, { maxBuffer: Infinity });
assert.deepStrictEqual(ret, msgOutBuf);
}
// maxBuffer size is Infinity at default.
{
const ret = execFileSync(
process.execPath,
['-e', "console.log('a'.repeat(200 * 1024))"],
{ encoding: 'utf-8' }
);
assert.ifError(ret.error);
}

View File

@ -0,0 +1,37 @@
'use strict';
require('../common');
// This test checks that the maxBuffer option for child_process.spawnSync()
// works as expected.
const assert = require('assert');
const { execSync } = require('child_process');
const msgOut = 'this is stdout';
const msgOutBuf = Buffer.from(`${msgOut}\n`);
const args = [
'-e',
`"console.log('${msgOut}')";`
];
// Verify that an error is returned if maxBuffer is surpassed.
{
assert.throws(() => {
execSync(`"${process.execPath}" ${args.join(' ')}`, { maxBuffer: 1 });
}, (e) => {
assert.ok(e, 'maxBuffer should error');
assert.strictEqual(e.errno, 'ENOBUFS');
assert.deepStrictEqual(e.stdout, msgOutBuf);
return true;
});
}
// Verify that a maxBuffer size of Infinity works.
{
const ret = execSync(
`"${process.execPath}" ${args.join(' ')}`,
{ maxBuffer: Infinity }
);
assert.deepStrictEqual(ret, msgOutBuf);
}

View File

@ -32,3 +32,11 @@ const args = [
assert.ifError(ret.error); assert.ifError(ret.error);
assert.deepStrictEqual(ret.stdout, msgOutBuf); assert.deepStrictEqual(ret.stdout, msgOutBuf);
} }
// maxBuffer size is Infinity at default.
{
const args = ['-e', "console.log('a'.repeat(200 * 1024))"];
const ret = spawnSync(process.execPath, args, { encoding: 'utf-8' });
assert.ifError(ret.error);
}