summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRandall Leeds <randall@apache.org>2016-02-20 18:44:16 -0800
committerRobert Newson <rnewson@apache.org>2016-09-09 14:10:10 +0100
commit33a71410ea7925ffa2da734e73db460d29f68cf7 (patch)
tree2eefa7c49c725c1217902f76627afb102a66769f
parent3841aedfb410864b7e7fa4fccbca71afa104bd91 (diff)
downloadcouchdb-33a71410ea7925ffa2da734e73db460d29f68cf7.tar.gz
use fresh sandbox for every compile
-rw-r--r--share/server/filter.js3
-rw-r--r--share/server/loop.js29
-rw-r--r--share/server/state.js1
-rw-r--r--share/server/util.js76
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([