diff options
author | Benety Goh <benety@mongodb.com> | 2016-01-08 15:47:18 -0500 |
---|---|---|
committer | Benety Goh <benety@mongodb.com> | 2016-01-12 10:10:58 -0500 |
commit | 28fe476b7e7e8d43461f20384b7072cd83ad30b7 (patch) | |
tree | 87b8f5692169cf960d52b34ceb08218aac9ca28e | |
parent | ee1daeddef9e19b6879add2e0082bb0300447f02 (diff) | |
download | mongo-28fe476b7e7e8d43461f20384b7072cd83ad30b7.tar.gz |
SERVER-22109 validate index spec namespace in applyOperation_inlock
(cherry picked from commit 51f0cfa865fe090a5208d5bff47faa5fbe6a92c1)
-rw-r--r-- | jstests/core/apply_ops1.js | 41 | ||||
-rw-r--r-- | src/mongo/db/repl/oplog.cpp | 15 |
2 files changed, 56 insertions, 0 deletions
diff --git a/jstests/core/apply_ops1.js b/jstests/core/apply_ops1.js index cd2b57216e8..430af6b62a3 100644 --- a/jstests/core/apply_ops1.js +++ b/jstests/core/apply_ops1.js @@ -45,6 +45,47 @@ 'applyOps should fail on non-"n" operation type with empty "ns" field value' ); + // Missing 'o' field value in an operation of type 'i' on 'system.indexes' collection. + assert.commandFailedWithCode( + db.adminCommand({applyOps: [{op: 'i', ns: db.getName() + '.system.indexes'}]}), + 4, // ErrorCodes.NoSuchKey + 'applyOps should fail on system.indexes insert operation without "o" field'); + + // Non-object 'o' field value in an operation of type 'i' on 'system.indexes' collection. + assert.commandFailedWithCode( + db.adminCommand({applyOps: [{op: 'i', ns: db.getName() + '.system.indexes', o: 'bar'}]}), + 14, // ErrorCodes.TypeMismatch + 'applyOps should fail on system.indexes insert operation with non-object "o" field'); + + // Missing 'ns' field in index spec. + assert.commandFailedWithCode( + db.adminCommand({applyOps: [{op: 'i', ns: db.getName() + '.system.indexes', o: { + key: {a: 1}, + name: 'a_1', + }}]}), + 4, // ErrorCodes.NoSuchKey + 'applyOps should fail on system.indexes insert operation with missing index namespace'); + + // Non-string 'ns' field in index spec. + assert.commandFailedWithCode( + db.adminCommand({applyOps: [{op: 'i', ns: db.getName() + '.system.indexes', o: { + ns: 12345, + key: {a: 1}, + name: 'a_1', + }}]}), + 14, // ErrorCodes.TypeMismatch + 'applyOps should fail on system.indexes insert operation with non-string index namespace'); + + // Invalid 'ns' field in index spec. + assert.commandFailedWithCode( + db.adminCommand({applyOps: [{op: 'i', ns: db.getName() + '.system.indexes', o: { + ns: 'invalid_namespace', + key: {a: 1}, + name: 'a_1', + }}]}), + 73, // ErrorCodes.InvalidNamespace + 'applyOps should fail on system.indexes insert operation with invalid index namespace'); + // Valid 'ns' field value in unknown operation type 'x'. assert.commandFailed( db.adminCommand({applyOps: [{op: 'x', ns: t.getFullName()}]}), diff --git a/src/mongo/db/repl/oplog.cpp b/src/mongo/db/repl/oplog.cpp index d33a9814f9c..1688a5be578 100644 --- a/src/mongo/db/repl/oplog.cpp +++ b/src/mongo/db/repl/oplog.cpp @@ -39,6 +39,7 @@ #include <boost/thread/recursive_mutex.hpp> +#include "mongo/bson/util/bson_extract.h" #include "mongo/db/auth/action_set.h" #include "mongo/db/auth/action_type.h" #include "mongo/db/auth/authorization_manager.h" @@ -633,6 +634,20 @@ bool applyOperation_inlock(OperationContext* txn, const char* p = strchr(ns, '.'); if (p && nsToCollectionSubstring(p) == "system.indexes") { + uassert(ErrorCodes::NoSuchKey, + str::stream() << "Missing expected index spec in field 'o': " << op, + !fieldO.eoo()); + uassert(ErrorCodes::TypeMismatch, + str::stream() << "Expected object for index spec in field 'o': " << op, + fieldO.isABSONObj()); + + std::string indexNs; + uassertStatusOK(bsonExtractStringField(o, "ns", &indexNs)); + const NamespaceString indexNss(indexNs); + uassert(ErrorCodes::InvalidNamespace, + str::stream() << "Invalid namespace in index spec: " << op, + indexNss.isValid()); + if (o["background"].trueValue()) { Lock::TempRelease release(txn->lockState()); if (txn->lockState()->isLocked()) { |