summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Hows <howsdav@gmail.com>2015-07-31 16:22:46 +1000
committerDavid Hows <david.hows@mongodb.com>2015-09-24 09:06:41 +1000
commit8efa1322b11574c7d4286cef56e937718aa5e2a1 (patch)
tree8a38fdbb1834f3b1e52d82c7fd173888bfe80baf
parent08eacba75fb15e397222f20af0bf48b26b54a0d5 (diff)
downloadmongo-8efa1322b11574c7d4286cef56e937718aa5e2a1.tar.gz
SERVER-19671 - Null chars in namespaces cause issues
-rw-r--r--jstests/noPassthroughWithMongod/newcollection2.js7
-rw-r--r--src/mongo/db/commands/apply_ops.cpp4
-rw-r--r--src/mongo/db/repl/oplog.cpp8
3 files changed, 15 insertions, 4 deletions
diff --git a/jstests/noPassthroughWithMongod/newcollection2.js b/jstests/noPassthroughWithMongod/newcollection2.js
index 86d5e9f7a3a..da13f6eadf2 100644
--- a/jstests/noPassthroughWithMongod/newcollection2.js
+++ b/jstests/noPassthroughWithMongod/newcollection2.js
@@ -8,3 +8,10 @@ db.createCollection( baseName, {size:0x1FFC0000-0x10-8192} );
var v = db[ baseName ].validate();
printjson( v );
assert( v.valid );
+
+// Try creating collections with some invalid names and confirm that they
+// don't crash MongoD.
+
+db.runCommand({ applyOps: [ { op: 'u', ns: 'a\0b' } ] });
+var res = db["a\0a"].insert({});
+assert(res.hasWriteError(), "A write to collection a\0a succceeded")
diff --git a/src/mongo/db/commands/apply_ops.cpp b/src/mongo/db/commands/apply_ops.cpp
index 7381d61dffc..6bab78adb6b 100644
--- a/src/mongo/db/commands/apply_ops.cpp
+++ b/src/mongo/db/commands/apply_ops.cpp
@@ -152,6 +152,10 @@ private:
errmsg = str::stream() << "\"ns\" field is not a string: " << e.fieldName();
return false;
}
+ if (nsElement.String().find('\0') != std::string::npos) {
+ errmsg = str::stream() << "namespaces cannot have embedded null characters";
+ return false;
+ }
if (*opType != 'n' && nsElement.String().empty()) {
errmsg = str::stream()
<< "\"ns\" field value cannot be empty when op type is not 'n': " << e.fieldName();
diff --git a/src/mongo/db/repl/oplog.cpp b/src/mongo/db/repl/oplog.cpp
index 341f55e8af1..90ce1efa98e 100644
--- a/src/mongo/db/repl/oplog.cpp
+++ b/src/mongo/db/repl/oplog.cpp
@@ -604,7 +604,7 @@ Status applyOperation_inlock(OperationContext* txn,
if (fieldO.isABSONObj())
o = fieldO.embeddedObject();
- const char* ns = fieldNs.valuestrsafe();
+ const StringData ns = fieldNs.valueStringData();
BSONObj o2;
if (fieldO2.isABSONObj())
@@ -633,8 +633,7 @@ Status applyOperation_inlock(OperationContext* txn,
if (*opType == 'i') {
opCounters->gotInsert();
- const char* p = strchr(ns, '.');
- if (p && nsToCollectionSubstring(p) == "system.indexes") {
+ if (nsToCollectionSubstring(ns) == "system.indexes") {
if (o["background"].trueValue()) {
IndexBuilder* builder = new IndexBuilder(o);
// This spawns a new thread and returns immediately.
@@ -790,7 +789,8 @@ Status applyOperation_inlock(OperationContext* txn,
// AuthorizationManager's logOp method registers a RecoveryUnit::Change
// and to do so we need to have begun a UnitOfWork
WriteUnitOfWork wuow(txn);
- getGlobalAuthorizationManager()->logOp(txn, opType, ns, o, fieldO2.isABSONObj() ? &o2 : NULL);
+ getGlobalAuthorizationManager()->logOp(
+ txn, opType, ns.toString().c_str(), o, fieldO2.isABSONObj() ? &o2 : NULL);
wuow.commit();
return Status::OK();