child_process: don't fork bomb ourselves from -e
authorBen Noordhuis <info@bnoordhuis.nl>
Wed, 28 Oct 2015 22:06:40 +0000 (23:06 +0100)
committerJames M Snell <jasnell@gmail.com>
Wed, 23 Dec 2015 16:38:33 +0000 (08:38 -0800)
Remove the `-e` argument from process.execArgv in child_process.fork()
to keep `node -e 'require("child_process").fork("empty.js")'` from
spawning itself recursively.

Fixes: https://github.com/nodejs/node/issues/3574
PR-URL: https://github.com/nodejs/node/pull/3575
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
lib/child_process.js
test/parallel/test-cli-eval.js

index 0fe9ca7..151fb51 100644 (file)
@@ -32,6 +32,16 @@ exports.fork = function(modulePath /*, args, options*/) {
 
   // Prepare arguments for fork:
   execArgv = options.execArgv || process.execArgv;
+
+  if (execArgv === process.execArgv && process._eval != null) {
+    const index = execArgv.lastIndexOf(process._eval);
+    if (index > 0) {
+      // Remove the -e switch to avoid fork bombing ourselves.
+      execArgv = execArgv.slice();
+      execArgv.splice(index - 1, 2);
+    }
+  }
+
   args = execArgv.concat([modulePath], args);
 
   // Leave stdin open for the IPC channel. stdout and stderr should be the
index 10a77c4..15f59c8 100644 (file)
@@ -8,6 +8,7 @@ if (module.parent) {
 var common = require('../common'),
     assert = require('assert'),
     child = require('child_process'),
+    path = require('path'),
     nodejs = '"' + process.execPath + '"';
 
 
@@ -75,3 +76,11 @@ child.exec(nodejs + ' --use-strict -p process.execArgv',
     function(status, stdout, stderr) {
       assert.equal(stdout, "[ '--use-strict', '-p', 'process.execArgv' ]\n");
     });
+
+// Regression test for https://github.com/nodejs/node/issues/3574
+const emptyFile = path.join(common.fixturesDir, 'empty.js');
+child.exec(nodejs + ` -e 'require("child_process").fork("${emptyFile}")'`,
+    function(status, stdout, stderr) {
+      assert.equal(stdout, '');
+      assert.equal(stderr, '');
+    });