You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by rn...@apache.org on 2016/09/09 13:28:34 UTC
[1/4] couchdb commit: updated refs/heads/master to d6abc18
Repository: couchdb
Updated Branches:
refs/heads/master aae4ff745 -> d6abc18f2
do not pollute the global scope
Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/4dbd858e
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/4dbd858e
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/4dbd858e
Branch: refs/heads/master
Commit: 4dbd858e4b3babb454a605f5d429e118f02c05b2
Parents: aae4ff7
Author: Randall Leeds <ra...@apache.org>
Authored: Sat Feb 20 18:28:24 2016 -0800
Committer: Robert Newson <rn...@apache.org>
Committed: Fri Sep 9 14:09:35 2016 +0100
----------------------------------------------------------------------
support/build_js.escript | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb/blob/4dbd858e/support/build_js.escript
----------------------------------------------------------------------
diff --git a/support/build_js.escript b/support/build_js.escript
index 5050fd6..0b3a859 100644
--- a/support/build_js.escript
+++ b/support/build_js.escript
@@ -40,13 +40,15 @@ main([]) ->
"share/server/coffee-script.js",
"share/server/loop.js"],
+ Pre = "(function () {\n",
+ Post = "})();\n",
Concat = fun(Files, To) ->
AccBin = lists:foldl(fun(Path, Acc) ->
{ok, Bin} = file:read_file(Path),
[Bin | Acc]
end, [], Files),
- FinalBin = iolist_to_binary(lists:reverse(AccBin)),
+ FinalBin = iolist_to_binary(Pre ++ lists:reverse(AccBin) ++ Post),
file:write_file(To, FinalBin)
end,
[3/4] couchdb commit: updated refs/heads/master to d6abc18
Posted by rn...@apache.org.
use fresh sandbox for every compile
Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/33a71410
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/33a71410
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/33a71410
Branch: refs/heads/master
Commit: 33a71410ea7925ffa2da734e73db460d29f68cf7
Parents: 3841aed
Author: Randall Leeds <ra...@apache.org>
Authored: Sat Feb 20 18:44:16 2016 -0800
Committer: Robert Newson <rn...@apache.org>
Committed: Fri Sep 9 14:10:10 2016 +0100
----------------------------------------------------------------------
share/server/filter.js | 3 +-
share/server/loop.js | 29 +++++------------
share/server/state.js | 1 -
share/server/util.js | 76 +++++++++++++++++++++------------------------
4 files changed, 45 insertions(+), 64 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb/blob/33a71410/share/server/filter.js
----------------------------------------------------------------------
diff --git a/share/server/filter.js b/share/server/filter.js
index ad29266..ddb6479 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];
http://git-wip-us.apache.org/repos/asf/couchdb/blob/33a71410/share/server/loop.js
----------------------------------------------------------------------
diff --git a/share/server/loop.js b/share/server/loop.js
index 1ded19b..f179839 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
//
http://git-wip-us.apache.org/repos/asf/couchdb/blob/33a71410/share/server/state.js
----------------------------------------------------------------------
diff --git a/share/server/state.js b/share/server/state.js
index b8ba046..ff553dd 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
},
http://git-wip-us.apache.org/repos/asf/couchdb/blob/33a71410/share/server/util.js
----------------------------------------------------------------------
diff --git a/share/server/util.js b/share/server/util.js
index 9e49970..e3ea90e 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([
[2/4] couchdb commit: updated refs/heads/master to d6abc18
Posted by rn...@apache.org.
seal exposed globals
Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/3841aedf
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/3841aedf
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/3841aedf
Branch: refs/heads/master
Commit: 3841aedfb410864b7e7fa4fccbca71afa104bd91
Parents: 4dbd858
Author: Randall Leeds <ra...@apache.org>
Authored: Sat Apr 23 19:32:03 2016 -0700
Committer: Robert Newson <rn...@apache.org>
Committed: Fri Sep 9 14:10:06 2016 +0100
----------------------------------------------------------------------
share/server/loop.js | 10 ++++++++++
share/server/render.js | 43 ++++++++++++++++++++++++++-----------------
2 files changed, 36 insertions(+), 17 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb/blob/3841aedf/share/server/loop.js
----------------------------------------------------------------------
diff --git a/share/server/loop.js b/share/server/loop.js
index 551004a..1ded19b 100644
--- a/share/server/loop.js
+++ b/share/server/loop.js
@@ -165,4 +165,14 @@ var Loop = function() {
};
};
+// Seal all the globals to prevent modification.
+seal(Couch, true);
+seal(JSON, true);
+seal(Mime, true);
+seal(Render, true);
+seal(Filter, true);
+seal(Views, true);
+seal(isArray, true);
+seal(log, true);
+
Loop();
http://git-wip-us.apache.org/repos/asf/couchdb/blob/3841aedf/share/server/render.js
----------------------------------------------------------------------
diff --git a/share/server/render.js b/share/server/render.js
index 1fe4da2..946701e 100644
--- a/share/server/render.js
+++ b/share/server/render.js
@@ -57,26 +57,29 @@ var Mime = (function() {
registerType("url_encoded_form", "application/x-www-form-urlencoded");
// http://www.ietf.org/rfc/rfc4627.txt
registerType("json", "application/json", "text/x-json");
-
-
+
+
+ var providesUsed = false;
var mimeFuns = [];
+ var responseContentType = null;
+
function provides(type, fun) {
- Mime.providesUsed = true;
+ providesUsed = true;
mimeFuns.push([type, fun]);
};
function resetProvides() {
// set globals
- Mime.providesUsed = false;
+ providesUsed = false;
mimeFuns = [];
- Mime.responseContentType = null;
+ responseContentType = null;
};
function runProvides(req, ddoc) {
var supportedMimes = [], bestFun, bestKey = null, accept = req.headers["Accept"];
if (req.query && req.query.format) {
bestKey = req.query.format;
- Mime.responseContentType = mimesByKey[bestKey][0];
+ responseContentType = mimesByKey[bestKey][0];
} else if (accept) {
// log("using accept header: "+accept);
mimeFuns.reverse().forEach(function(mimeFun) {
@@ -85,12 +88,12 @@ var Mime = (function() {
supportedMimes = supportedMimes.concat(mimesByKey[mimeKey]);
}
});
- Mime.responseContentType = Mimeparse.bestMatch(supportedMimes, accept);
- bestKey = keysByMime[Mime.responseContentType];
+ responseContentType = Mimeparse.bestMatch(supportedMimes, accept);
+ bestKey = keysByMime[responseContentType];
} else {
// just do the first one
bestKey = mimeFuns[0][0];
- Mime.responseContentType = mimesByKey[bestKey][0];
+ responseContentType = mimesByKey[bestKey][0];
}
if (bestKey) {
@@ -113,12 +116,18 @@ var Mime = (function() {
}
};
-
+
return {
registerType : registerType,
provides : provides,
resetProvides : resetProvides,
- runProvides : runProvides
+ runProvides : runProvides,
+ providesUsed : function () {
+ return providesUsed;
+ },
+ responseContentType : function () {
+ return responseContentType;
+ }
};
})();
@@ -145,7 +154,7 @@ var Render = (function() {
};
function sendStart() {
- startResp = applyContentType((startResp || {}), Mime.responseContentType);
+ startResp = applyContentType((startResp || {}), Mime.responseContentType());
respond(["start", chunks, startResp]);
chunks = [];
startResp = {};
@@ -155,7 +164,7 @@ var Render = (function() {
function applyContentType(resp, responseContentType) {
resp["headers"] = resp["headers"] || {};
if (responseContentType) {
- resp["headers"]["Content-Type"] = resp["headers"]["Content-Type"] || responseContentType;
+ resp["headers"]["Content-Type"] = resp["headers"]["Content-Type"] || responseContentType;
}
return resp;
}
@@ -242,12 +251,12 @@ var Render = (function() {
resetList();
}
- if (Mime.providesUsed) {
+ if (Mime.providesUsed()) {
var provided_resp = Mime.runProvides(args[1], ddoc) || {};
provided_resp = maybeWrapResponse(provided_resp);
resp.body = (resp.body || "") + chunks.join("");
resp.body += provided_resp.body || "";
- resp = applyContentType(resp, Mime.responseContentType);
+ resp = applyContentType(resp, Mime.responseContentType());
resetList();
}
@@ -301,9 +310,9 @@ var Render = (function() {
var req = args[1];
var tail = listFun.apply(ddoc, args);
- if (Mime.providesUsed) {
+ if (Mime.providesUsed()) {
tail = Mime.runProvides(req, ddoc);
- }
+ }
if (!gotRow) getRow();
if (typeof tail != "undefined") {
chunks.push(tail);
[4/4] couchdb commit: updated refs/heads/master to d6abc18
Posted by rn...@apache.org.
option to disable runtime code evaluation
Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/d6abc18f
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/d6abc18f
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/d6abc18f
Branch: refs/heads/master
Commit: d6abc18f27b7b0d0d6cf3e88d25c8066900958a1
Parents: 33a7141
Author: Randall Leeds <ra...@apache.org>
Authored: Sat Apr 23 17:49:34 2016 -0700
Committer: Robert Newson <rn...@apache.org>
Committed: Fri Sep 9 14:27:56 2016 +0100
----------------------------------------------------------------------
rebar.config.script | 2 +-
test/javascript/tests/view_sandboxing.js | 41 +++++++++++++++++++++++++++
2 files changed, 42 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb/blob/d6abc18f/rebar.config.script
----------------------------------------------------------------------
diff --git a/rebar.config.script b/rebar.config.script
index cece0f9..104006e 100644
--- a/rebar.config.script
+++ b/rebar.config.script
@@ -29,7 +29,7 @@ DepDescs = [
{b64url, "b64url", "6895652d80f95cdf04efb14625abed868998f174"},
{couch_log, "couch-log", "ad803f66dbd1900b67543259142875a6d03503ce"},
{chttpd, "chttpd", "c6b044006fcb58386099105fb6d9e0a036a62ed9"},
-{couch, "couch", "72869b8bf139ffc2542d02a2bd3b862042a668c3"},
+{couch, "couch", "092dec86bbf068e0ab99f6586668260515fc86a9"},
{couch_index, "couch-index", "53555fd909d5dd3d4a610c3fd6795950a8f7d022"},
{couch_mrview, "couch-mrview", "a0b0392afe66ece9ef3bb4fdd5a4f159c97c47eb"},
{couch_replicator, "couch-replicator", "b9232c8d410d529d65030896e075c4b4327631b0"},
http://git-wip-us.apache.org/repos/asf/couchdb/blob/d6abc18f/test/javascript/tests/view_sandboxing.js
----------------------------------------------------------------------
diff --git a/test/javascript/tests/view_sandboxing.js b/test/javascript/tests/view_sandboxing.js
index c70eecc..171777b 100644
--- a/test/javascript/tests/view_sandboxing.js
+++ b/test/javascript/tests/view_sandboxing.js
@@ -145,6 +145,47 @@ couchTests.view_sandboxing = function(debug) {
}
*/
+ // test that runtime code evaluation can be prevented
+ console.log('TODO: config port not available on cluster');
+ /*var couchjs_command_xhr = CouchDB.request(
+ "GET", "/_config/query_servers/javascript");
+
+ var couchjs_command = JSON.parse(couchjs_command_xhr.responseText);
+ var couchjs_command_args = couchjs_command.match(/\S+|"(?:\\"|[^"])+"/g);
+
+ couchjs_command_args.splice(1, 0, "--no-eval");
+ var new_couchjs_command = couchjs_command_args.join(" ");
+
+ run_on_modified_server(
+ [{section: "query_servers",
+ key: "javascript",
+ value: new_couchjs_command}],
+ function () {
+ var ddoc = {
+ _id: "_design/foobar",
+ language: "javascript",
+ views: {
+ view: {
+ map:
+ (function(doc) {
+ var glob = emit.constructor('return this')();
+ emit(doc._id, null);
+ }).toString()
+ }
+ }
+ };
+
+ db.deleteDb();
+ db.createDb();
+ T(db.save(ddoc).ok);
+
+ T(db.save(doc).ok);
+ var results = db.view(
+ "foobar/view", {bypass_cache: Math.round(Math.random() * 1000)});
+
+ TEquals(0, results.rows.length);
+ });*/
+
// cleanup
db.deleteDb();
};