From 1f653f61956693e9c646c484cf077f1d5cce1572 Mon Sep 17 00:00:00 2001 From: cjihrig Date: Thu, 12 Nov 2015 14:30:20 -0500 Subject: [PATCH] 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 Reviewed-By: Evan Lucas Reviewed-By: James M Snell --- lib/child_process.js | 81 +++++++++++++++++++++++++------------------- 1 file changed, 47 insertions(+), 34 deletions(-) diff --git a/lib/child_process.js b/lib/child_process.js index 151fb51fc8b0f4..ddbb0448d90c20 100644 --- a/lib/child_process.js +++ b/lib/child_process.js @@ -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 (stdoutLen > options.maxBuffer) { - ex = new Error('stdout maxBuffer exceeded.'); - kill(); - } else { - if (!encoding) - _stdout.push(chunk); - else - _stdout += chunk; - } - }); - - 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; - } - }); + if (child.stdout) { + if (encoding) + child.stdout.setEncoding(encoding); + + child.stdout.addListener('data', function(chunk) { + stdoutLen += chunk.length; + + if (stdoutLen > options.maxBuffer) { + ex = new Error('stdout maxBuffer exceeded'); + kill(); + } else { + if (!encoding) + _stdout.push(chunk); + else + _stdout += chunk; + } + }); + } - if (encoding) { - child.stderr.setEncoding(encoding); - child.stdout.setEncoding(encoding); + if (child.stderr) { + if (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);