summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBenety Goh <benety@mongodb.com>2017-06-28 09:42:16 -0400
committerBenety Goh <benety@mongodb.com>2017-06-28 19:16:29 -0400
commita72d5e357fc0e8b31e705cba539762cd79093773 (patch)
treed9f62f819f44598e33b7416e717079d2440764c8 /src
parentf577af234306bdceeb27c5ec09606143d7347f9d (diff)
downloadmongo-a72d5e357fc0e8b31e705cba539762cd79093773.tar.gz
SERVER-21779 validate DB.runCommand(commandObjOrName, extraKeys) arguments.
When the command object is passed in as the first argument, any non-empty 'extraKeys' object will return an error.
Diffstat (limited to 'src')
-rw-r--r--src/mongo/shell/db.js45
1 files changed, 38 insertions, 7 deletions
diff --git a/src/mongo/shell/db.js b/src/mongo/shell/db.js
index 16f6f48b8f1..97bc38f5cec 100644
--- a/src/mongo/shell/db.js
+++ b/src/mongo/shell/db.js
@@ -66,21 +66,47 @@ var DB;
return cmdObjWithReadPref;
};
- // if someone passes i.e. runCommand("foo", {bar: "baz"}
- // we merge it in to runCommand({foo: 1, bar: "baz"}
- // this helper abstracts that logic.
- DB.prototype._mergeCommandOptions = function(commandName, extraKeys) {
+ /**
+ * If someone passes i.e. runCommand("foo", {bar: "baz"}), we merge it in to
+ * runCommand({foo: 1, bar: "baz"}).
+ * If we already have a command object in the first argument, we ensure that the second
+ * argument 'extraKeys' is either null or an empty object. This prevents users from accidentally
+ * calling runCommand({foo: 1}, {bar: 1}) and expecting the final command invocation to be
+ * runCommand({foo: 1, bar: 1}).
+ * This helper abstracts that logic.
+ */
+ DB.prototype._mergeCommandOptions = function(obj, extraKeys) {
"use strict";
+
+ if (typeof(obj) === "object") {
+ if (Object.keys(extraKeys || {}).length > 0) {
+ throw Error("Unexpected second argument to DB.runCommand(): (type: " +
+ typeof(extraKeys) + "): " + tojson(extraKeys));
+ }
+ return obj;
+ } else if (typeof(obj) !== "string") {
+ throw Error("First argument to DB.runCommand() must be either an object or a string: " +
+ "(type: " + typeof(obj) + "): " + tojson(obj));
+ }
+
+ var commandName = obj;
var mergedCmdObj = {};
mergedCmdObj[commandName] = 1;
- if (typeof(extraKeys) === "object") {
+ if (!extraKeys) {
+ return mergedCmdObj;
+ } else if (typeof(extraKeys) === "object") {
// this will traverse the prototype chain of extra, but keeping
// to maintain legacy behavior
for (var key in extraKeys) {
mergedCmdObj[key] = extraKeys[key];
}
+ } else {
+ throw Error("Second argument to DB.runCommand(" + commandName +
+ ") must be an object: (type: " + typeof(extraKeys) + "): " +
+ tojson(extraKeys));
}
+
return mergedCmdObj;
};
@@ -91,7 +117,7 @@ var DB;
// Support users who call this function with a string commandName, e.g.
// db.runReadCommand("commandName", {arg1: "value", arg2: "value"}).
- var mergedObj = (typeof(obj) === "string") ? this._mergeCommandOptions(obj, extra) : obj;
+ var mergedObj = this._mergeCommandOptions(obj, extra);
var cmdObjWithReadPref =
this._attachReadPreferenceToCommand(mergedObj, this.getMongo().getReadPref());
@@ -115,7 +141,12 @@ var DB;
};
DB.prototype.runCommand = function(obj, extra, queryOptions) {
- var mergedObj = (typeof(obj) === "string") ? this._mergeCommandOptions(obj, extra) : obj;
+ "use strict";
+
+ // Support users who call this function with a string commandName, e.g.
+ // db.runCommand("commandName", {arg1: "value", arg2: "value"}).
+ var mergedObj = this._mergeCommandOptions(obj, extra);
+
// if options were passed (i.e. because they were overridden on a collection), use them.
// Otherwise use getQueryOptions.
var options =