Skip to content

Commit 8f3ff98

Browse files
committed
child_process: allow Infinity as maxBuffer value
Fixes: #10767 PR-URL: #10769 Reviewed-By: James M Snell <[email protected]>
1 parent 0f0f3d3 commit 8f3ff98

File tree

5 files changed

+56
-24
lines changed

5 files changed

+56
-24
lines changed

lib/child_process.js

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,12 @@ exports.execFile = function(file /*, args, options, callback*/) {
146146
throw new TypeError('Incorrect value of args option');
147147
}
148148

149+
// Validate the timeout, if present.
150+
validateTimeout(options.timeout);
151+
152+
// Validate maxBuffer, if present.
153+
validateMaxBuffer(options.maxBuffer);
154+
149155
var child = spawn(file, args, {
150156
cwd: options.cwd,
151157
env: options.env,
@@ -466,31 +472,17 @@ function spawnSync(/*file, args, options*/) {
466472
debug('spawnSync', opts.args, options);
467473

468474
// Validate the timeout, if present.
469-
if (options.timeout != null &&
470-
!(Number.isInteger(options.timeout) && options.timeout >= 0)) {
471-
throw new TypeError('"timeout" must be an unsigned integer');
472-
}
475+
validateTimeout(options.timeout);
473476

474477
// Validate maxBuffer, if present.
475-
if (options.maxBuffer != null &&
476-
!(Number.isInteger(options.maxBuffer) && options.maxBuffer >= 0)) {
477-
throw new TypeError('"maxBuffer" must be an unsigned integer');
478-
}
478+
validateMaxBuffer(options.maxBuffer);
479479

480480
options.file = opts.file;
481481
options.args = opts.args;
482482
options.envPairs = opts.envPairs;
483483

484-
// Validate the kill signal, if present.
485-
if (typeof options.killSignal === 'string' ||
486-
typeof options.killSignal === 'number') {
487-
options.killSignal = lookupSignal(options.killSignal);
488-
489-
if (options.killSignal === 0)
490-
throw new RangeError('"killSignal" cannot be 0');
491-
} else if (options.killSignal != null) {
492-
throw new TypeError('"killSignal" must be a string or number');
493-
}
484+
// Validate and translate the kill signal, if present.
485+
options.killSignal = validateKillSignal(options.killSignal);
494486

495487
options.stdio = _validateStdio(options.stdio || 'pipe', true).stdio;
496488

@@ -600,3 +592,31 @@ function execSync(command /*, options*/) {
600592
return ret.stdout;
601593
}
602594
exports.execSync = execSync;
595+
596+
597+
function validateTimeout(timeout) {
598+
if (timeout != null && !(Number.isInteger(timeout) && timeout >= 0)) {
599+
throw new TypeError('"timeout" must be an unsigned integer');
600+
}
601+
}
602+
603+
604+
function validateMaxBuffer(maxBuffer) {
605+
if (maxBuffer != null && !(typeof maxBuffer === 'number' && maxBuffer >= 0)) {
606+
throw new TypeError('"maxBuffer" must be a positive number');
607+
}
608+
}
609+
610+
611+
function validateKillSignal(killSignal) {
612+
if (typeof killSignal === 'string' || typeof killSignal === 'number') {
613+
killSignal = lookupSignal(killSignal);
614+
615+
if (killSignal === 0)
616+
throw new RangeError('"killSignal" cannot be 0');
617+
} else if (killSignal != null) {
618+
throw new TypeError('"killSignal" must be a string or number');
619+
}
620+
621+
return killSignal;
622+
}

src/spawn_sync.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -765,8 +765,8 @@ int SyncProcessRunner::ParseOptions(Local<Value> js_value) {
765765

766766
Local<Value> js_max_buffer = js_options->Get(env()->max_buffer_string());
767767
if (IsSet(js_max_buffer)) {
768-
CHECK(js_max_buffer->IsUint32());
769-
max_buffer_ = js_max_buffer->Uint32Value();
768+
CHECK(js_max_buffer->IsNumber());
769+
max_buffer_ = js_max_buffer->NumberValue();
770770
}
771771

772772
Local<Value> js_kill_signal = js_options->Get(env()->kill_signal_string());

src/spawn_sync.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ class SyncProcessRunner {
184184
static void KillTimerCallback(uv_timer_t* handle);
185185
static void KillTimerCloseCallback(uv_handle_t* handle);
186186

187-
size_t max_buffer_;
187+
double max_buffer_;
188188
uint64_t timeout_;
189189
int kill_signal_;
190190

test/parallel/test-child-process-exec-maxBuffer.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,17 @@ function checkFactory(streamName) {
1010
});
1111
}
1212

13+
{
14+
const cmd = `"${process.execPath}" -e "console.log('hello world');"`;
15+
const options = { maxBuffer: Infinity };
16+
17+
cp.exec(cmd, options, common.mustCall((err, stdout, stderr) => {
18+
assert.ifError(err);
19+
assert.strictEqual(stdout.trim(), 'hello world');
20+
assert.strictEqual(stderr, '');
21+
}));
22+
}
23+
1324
{
1425
const cmd = 'echo "hello world"';
1526

test/parallel/test-child-process-spawnsync-validation-errors.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -163,16 +163,17 @@ if (!common.isWindows) {
163163

164164
{
165165
// Validate the maxBuffer option
166-
const err = /^TypeError: "maxBuffer" must be an unsigned integer$/;
166+
const err = /^TypeError: "maxBuffer" must be a positive number$/;
167167

168168
pass('maxBuffer', undefined);
169169
pass('maxBuffer', null);
170170
pass('maxBuffer', 1);
171171
pass('maxBuffer', 0);
172-
fail('maxBuffer', 3.14, err);
172+
pass('maxBuffer', Infinity);
173+
pass('maxBuffer', 3.14);
173174
fail('maxBuffer', -1, err);
174175
fail('maxBuffer', NaN, err);
175-
fail('maxBuffer', Infinity, err);
176+
fail('maxBuffer', -Infinity, err);
176177
fail('maxBuffer', true, err);
177178
fail('maxBuffer', false, err);
178179
fail('maxBuffer', __dirname, err);

0 commit comments

Comments
 (0)