From 610574b5fc4acf887a7a07267da400e780a923fe Mon Sep 17 00:00:00 2001 From: John Hawthorn Date: Mon, 10 Oct 2016 03:19:38 -0700 Subject: [PATCH] Use node's vm module to run in clean context As suggested by Joshua Peek in a previous issue. Node's vm module gives us full control over the globals passed to the context the code is run in. In order to do this we store our code as a JS string, wrap it in an IFFE (to support the `return` symantics we use for all runtimes) vm.runInNewContext is called with {filename: "(execjs)"} in order to have the proper filename appear in backtraces. Normally this string is inserted into backtraces via a gsub in external_runtime.rb which replaces the filename. See https://nodejs.org/api/vm.html --- lib/execjs/support/node_runner.js | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/lib/execjs/support/node_runner.js b/lib/execjs/support/node_runner.js index 2987d9f..84684c3 100644 --- a/lib/execjs/support/node_runner.js +++ b/lib/execjs/support/node_runner.js @@ -1,20 +1,17 @@ -(function(program, execJS) { execJS(program) })(function(global, process, module, exports, require, console, setTimeout, setInterval, clearTimeout, clearInterval, setImmediate, clearImmediate) { #{source} -}, function(program) { +(function(execJS) { execJS() })(function() { + var source = #{::JSON.dump(source)}; + source = "(function(){"+ source + "})()"; + var output, print = function(string) { process.stdout.write('' + string); }; try { - var __process__ = process; - delete this.process; - delete this.console; - delete this.setTimeout; - delete this.setInterval; - delete this.clearTimeout; - delete this.clearInterval; - delete this.setImmediate; - delete this.clearImmediate; + var program = function(){ + var vm = require('vm'); + var script = new vm.Script(source, {filename: "(execjs)"}); + return script.runInNewContext(); + } result = program(); - this.process = __process__; if (typeof result == 'undefined' && result !== null) { print('["ok"]'); } else { @@ -25,7 +22,6 @@ } } } catch (err) { - this.process = __process__; print(JSON.stringify(['err', '' + err, err.stack])); } });