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>
This commit is contained in:
cjihrig 2015-11-12 14:30:20 -05:00 коммит произвёл James M Snell
Родитель f8390fdd75
Коммит 7b355c5bb3
1 изменённых файлов: 44 добавлений и 31 удалений

Просмотреть файл

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