summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--jstests/core/function_string_representations.js38
-rw-r--r--src/mongo/scripting/mozjs/mongohelpers.js8
2 files changed, 46 insertions, 0 deletions
diff --git a/jstests/core/function_string_representations.js b/jstests/core/function_string_representations.js
new file mode 100644
index 00000000000..af66e9160a9
--- /dev/null
+++ b/jstests/core/function_string_representations.js
@@ -0,0 +1,38 @@
+/** Demonstrate that mapReduce can accept functions represented by strings.
+ * Some drivers do not have a type which represents a Javascript function. These languages represent
+ * the arguments to mapReduce as strings.
+ */
+
+(function() {
+ "use strict";
+
+ var col = db.function_string_representations;
+ col.drop();
+ assert.writeOK(col.insert({
+ _id: "abc123",
+ ord_date: new Date("Oct 04, 2012"),
+ status: 'A',
+ price: 25,
+ items: [{sku: "mmm", qty: 5, price: 2.5}, {sku: "nnn", qty: 5, price: 2.5}]
+ }));
+
+ var mapFunction = "function() {emit(this._id, this.price);}";
+ var reduceFunction = "function(keyCustId, valuesPrices) {return Array.sum(valuesPrices);}";
+ assert.commandWorked(col.mapReduce(mapFunction, reduceFunction, {out: "map_reduce_example"}));
+
+ // Provided strings may end with semicolons and/or whitespace
+ mapFunction += " ; ";
+ reduceFunction += " ; ";
+ assert.commandWorked(col.mapReduce(mapFunction, reduceFunction, {out: "map_reduce_example"}));
+
+ // $where exhibits the same behavior
+ var whereFunction = "function() {return this.price === 25;}";
+ assert.eq(1, col.find({$where: whereFunction}).itcount());
+
+ whereFunction += ";";
+ assert.eq(1, col.find({$where: whereFunction}).itcount());
+
+ // db.eval does not need to be tested, as it accepts code fragments, not functions.
+ // system.js does not need to be tested, as its contents types' are preserved, and
+ // strings are not promoted into functions.
+})();
diff --git a/src/mongo/scripting/mozjs/mongohelpers.js b/src/mongo/scripting/mozjs/mongohelpers.js
index b0b35bb2fe8..d3f743623a3 100644
--- a/src/mongo/scripting/mozjs/mongohelpers.js
+++ b/src/mongo/scripting/mozjs/mongohelpers.js
@@ -33,6 +33,14 @@
exportToMongoHelpers = {
// This function accepts an expression or function body and returns a function definition
'functionExpressionParser': function functionExpressionParser(fnSrc) {
+
+ // Ensure that a provided expression or function body is not terminated with a ';'.
+ // This ensures we interpret the input as a single expression, rather than a sequence
+ // of expressions, and can wrap it in parentheses.
+ while (fnSrc.endsWith(";") || fnSrc != fnSrc.trimRight()) {
+ fnSrc = fnSrc.slice(0, -1).trimRight();
+ }
+
var parseTree;
try {
parseTree = this.Reflect.parse(fnSrc);