diff options
author | Benety Goh <benety@mongodb.com> | 2017-06-28 09:42:16 -0400 |
---|---|---|
committer | Benety Goh <benety@mongodb.com> | 2017-06-28 19:16:29 -0400 |
commit | a72d5e357fc0e8b31e705cba539762cd79093773 (patch) | |
tree | d9f62f819f44598e33b7416e717079d2440764c8 /src | |
parent | f577af234306bdceeb27c5ec09606143d7347f9d (diff) | |
download | mongo-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.js | 45 |
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 = |