diff options
author | Randall Leeds <randall@apache.org> | 2016-02-20 18:44:16 -0800 |
---|---|---|
committer | Robert Newson <rnewson@apache.org> | 2016-09-09 14:10:10 +0100 |
commit | 33a71410ea7925ffa2da734e73db460d29f68cf7 (patch) | |
tree | 2eefa7c49c725c1217902f76627afb102a66769f | |
parent | 3841aedfb410864b7e7fa4fccbca71afa104bd91 (diff) | |
download | couchdb-33a71410ea7925ffa2da734e73db460d29f68cf7.tar.gz |
use fresh sandbox for every compile
-rw-r--r-- | share/server/filter.js | 3 | ||||
-rw-r--r-- | share/server/loop.js | 29 | ||||
-rw-r--r-- | share/server/state.js | 1 | ||||
-rw-r--r-- | share/server/util.js | 76 |
4 files changed, 45 insertions, 64 deletions
diff --git a/share/server/filter.js b/share/server/filter.js index ad2926692..ddb6479bb 100644 --- a/share/server/filter.js +++ b/share/server/filter.js @@ -29,8 +29,9 @@ var Filter = (function() { }, filter_view : function(fun, ddoc, args) { // recompile + var sandbox = create_filter_sandbox(); var source = fun.toSource ? fun.toSource() : '(' + fun.toString() + ')'; - fun = evalcx(source, filter_sandbox); + fun = evalcx(source, sandbox); var results = []; var docs = args[0]; diff --git a/share/server/loop.js b/share/server/loop.js index 1ded19b8a..f17983940 100644 --- a/share/server/loop.js +++ b/share/server/loop.js @@ -10,13 +10,10 @@ // License for the specific language governing permissions and limitations under // the License. -var sandbox = null; -var filter_sandbox = null; - -function init_sandbox() { +function create_sandbox() { try { // if possible, use evalcx (not always available) - sandbox = evalcx(''); + var sandbox = evalcx(''); sandbox.emit = Views.emit; sandbox.sum = Views.sum; sandbox.log = log; @@ -29,27 +26,17 @@ function init_sandbox() { sandbox.getRow = Render.getRow; sandbox.isArray = isArray; } catch (e) { - //log(e.toSource()); + var sandbox = {}; } + return sandbox; }; -init_sandbox(); -function init_filter_sandbox() { - try { - filter_sandbox = evalcx(''); - for (var p in sandbox) { - if (sandbox.hasOwnProperty(p)) { - filter_sandbox[p] = sandbox[p]; - } - } - filter_sandbox.emit = Filter.emit; - } catch(e) { - log(e.toSource ? e.toSource() : e.stack); - } +function create_filter_sandbox() { + var sandbox = create_sandbox(); + sandbox.emit = Filter.emit; + return sandbox; }; -init_filter_sandbox(); - // Commands are in the form of json arrays: // ["commandname",..optional args...]\n // diff --git a/share/server/state.js b/share/server/state.js index b8ba04627..ff553dd57 100644 --- a/share/server/state.js +++ b/share/server/state.js @@ -16,7 +16,6 @@ var State = { State.funs = []; State.lib = null; State.query_config = config || {}; - init_sandbox(); gc(); print("true"); // indicates success }, diff --git a/share/server/util.js b/share/server/util.js index 9e4997031..e3ea90e87 100644 --- a/share/server/util.js +++ b/share/server/util.js @@ -61,52 +61,46 @@ var Couch = { compileFunction : function(source, ddoc, name) { if (!source) throw(["error","not_found","missing function"]); - var evaluate_function_source = function(source, evalFunction, sandbox) { - sandbox = sandbox || {}; - if(typeof CoffeeScript === "undefined") { - return evalFunction(source, sandbox, name); - } else { - var coffee = CoffeeScript.compile(source, {bare: true}); - return evalFunction(coffee, sandbox, name); + var functionObject = null; + var sandbox = create_sandbox(); + + var require = function(name, module) { + module = module || {}; + var newModule = resolveModule(name.split('/'), module.parent, ddoc); + if (!ddoc._module_cache.hasOwnProperty(newModule.id)) { + // create empty exports object before executing the module, + // stops circular requires from filling the stack + ddoc._module_cache[newModule.id] = {}; + var s = "function (module, exports, require) { " + newModule.current + "\n }"; + try { + var func = sandbox ? evalcx(s, sandbox, newModule.id) : eval(s); + func.apply(sandbox, [newModule, newModule.exports, function(name) { + return require(name, newModule); + }]); + } catch(e) { + throw [ + "error", + "compilation_error", + "Module require('" +name+ "') raised error " + + (e.toSource ? e.toSource() : e.stack) + ]; + } + ddoc._module_cache[newModule.id] = newModule.exports; } + return ddoc._module_cache[newModule.id]; + }; + + if (ddoc) { + sandbox.require = require; + if (!ddoc._module_cache) ddoc._module_cache = {}; } try { - if (sandbox) { - if (ddoc) { - if (!ddoc._module_cache) { - ddoc._module_cache = {}; - } - var require = function(name, module) { - module = module || {}; - var newModule = resolveModule(name.split('/'), module.parent, ddoc); - if (!ddoc._module_cache.hasOwnProperty(newModule.id)) { - // create empty exports object before executing the module, - // stops circular requires from filling the stack - ddoc._module_cache[newModule.id] = {}; - var s = "function (module, exports, require) { " + newModule.current + "\n }"; - try { - var func = sandbox ? evalcx(s, sandbox, newModule.id) : eval(s); - func.apply(sandbox, [newModule, newModule.exports, function(name) { - return require(name, newModule); - }]); - } catch(e) { - throw [ - "error", - "compilation_error", - "Module require('" +name+ "') raised error " + - (e.toSource ? e.toSource() : e.stack) - ]; - } - ddoc._module_cache[newModule.id] = newModule.exports; - } - return ddoc._module_cache[newModule.id]; - }; - sandbox.require = require; - } - var functionObject = evaluate_function_source(source, evalcx, sandbox); + if(typeof CoffeeScript === "undefined") { + functionObject = evalcx(source, sandbox, name); } else { - var functionObject = evaluate_function_source(source, eval); + var transpiled = CoffeeScript.compile(source, {bare: true}); + functionObject = evalcx(transpiled, sandbox, name); } } catch (err) { throw([ |