Browse Source

child_process: add safety checks on stdio access

When a child process is spawned, there is no guarantee that stdout
and stderr will be created successfully. This commit adds checks
before attempting to access the streams.

PR-URL: https://github.com/nodejs/node/pull/3799
Reviewed-By: Brian White <mscdex@mscdex.net>
Reviewed-By: Evan Lucas <evanlucas@me.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
process-exit-stdio-flushing
cjihrig 9 years ago
committed by James M Snell
parent
commit
7b355c5bb3
  1. 81
      lib/child_process.js

81
lib/child_process.js

@ -222,14 +222,22 @@ exports.execFile = function(file /*, args, options, callback*/) {
function errorhandler(e) { function errorhandler(e) {
ex = e; ex = e;
child.stdout.destroy();
child.stderr.destroy(); if (child.stdout)
child.stdout.destroy();
if (child.stderr)
child.stderr.destroy();
exithandler(); exithandler();
} }
function kill() { function kill() {
child.stdout.destroy(); if (child.stdout)
child.stderr.destroy(); child.stdout.destroy();
if (child.stderr)
child.stderr.destroy();
killed = true; killed = true;
try { try {
@ -247,37 +255,42 @@ exports.execFile = function(file /*, args, options, callback*/) {
}, options.timeout); }, options.timeout);
} }
child.stdout.addListener('data', function(chunk) { if (child.stdout) {
stdoutLen += chunk.length; if (encoding)
child.stdout.setEncoding(encoding);
if (stdoutLen > options.maxBuffer) {
ex = new Error('stdout maxBuffer exceeded'); child.stdout.addListener('data', function(chunk) {
kill(); stdoutLen += chunk.length;
} else {
if (!encoding) if (stdoutLen > options.maxBuffer) {
_stdout.push(chunk); ex = new Error('stdout maxBuffer exceeded');
else kill();
_stdout += chunk; } else {
} if (!encoding)
}); _stdout.push(chunk);
else
child.stderr.addListener('data', function(chunk) { _stdout += chunk;
stderrLen += chunk.length; }
});
if (stderrLen > options.maxBuffer) { }
ex = new Error('stderr maxBuffer exceeded');
kill();
} else {
if (!encoding)
_stderr.push(chunk);
else
_stderr += chunk;
}
});
if (encoding) { if (child.stderr) {
child.stderr.setEncoding(encoding); if (encoding)
child.stdout.setEncoding(encoding); child.stderr.setEncoding(encoding);
child.stderr.addListener('data', function(chunk) {
stderrLen += chunk.length;
if (stderrLen > options.maxBuffer) {
ex = new Error('stderr maxBuffer exceeded');
kill();
} else {
if (!encoding)
_stderr.push(chunk);
else
_stderr += chunk;
}
});
} }
child.addListener('close', exithandler); child.addListener('close', exithandler);

Loading…
Cancel
Save