summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Milkie <milkie@10gen.com>2013-05-13 17:25:41 -0400
committerEric Milkie <milkie@10gen.com>2013-05-15 14:26:44 -0400
commit7030cc8148131c8ac4910dd316929019f1909468 (patch)
treee9a3a9a42a93b677796f5e40173dc25b087dd309
parentb4c5ac3579fff46b19b927bf4a51b11cb262fc3a (diff)
downloadmongo-7030cc8148131c8ac4910dd316929019f1909468.tar.gz
SERVER-9502 prohibit _id as RegEx
Otherwise, this breaks when replication attempts to do a query with the regular expression as _id.
-rw-r--r--jstests/replsets/regex.js19
-rw-r--r--src/mongo/db/instance.cpp12
-rw-r--r--src/mongo/db/jsobj.cpp7
3 files changed, 36 insertions, 2 deletions
diff --git a/jstests/replsets/regex.js b/jstests/replsets/regex.js
new file mode 100644
index 00000000000..0a2db95acb4
--- /dev/null
+++ b/jstests/replsets/regex.js
@@ -0,0 +1,19 @@
+// don't allow regex as _id: SERVER-9502
+
+var replTest = new ReplSetTest( {name: "server9502", nodes: 2} );
+var nodes = replTest.startSet();
+replTest.initiate();
+var master = replTest.getMaster();
+var mdb = master.getDB("test");
+mdb.foo.insert({ _id: "ABCDEF" });
+var gle = master.getDB("test").runCommand({getLastError : 1, w : 2, wtimeout : 60000});
+assert(gle.err === null);
+
+mdb.foo.insert({ _id: /^A/ });
+var gle = master.getDB("test").runCommand({getLastError : 1, w : 2, wtimeout : 60000});
+assert(gle.code === 16814);
+
+// _id doesn't have to be first; still disallowed
+mdb.foo.insert({ xxx: "ABCDEF", _id: /ABCDEF/ });
+var gle = master.getDB("test").runCommand({getLastError : 1, w : 2, wtimeout : 60000});
+assert(gle.code === 16814);
diff --git a/src/mongo/db/instance.cpp b/src/mongo/db/instance.cpp
index 39f35945610..225ae66120c 100644
--- a/src/mongo/db/instance.cpp
+++ b/src/mongo/db/instance.cpp
@@ -742,13 +742,21 @@ namespace mongo {
void checkAndInsert(const char *ns, /*modifies*/BSONObj& js) {
uassert( 10059 , "object to insert too large", js.objsize() <= BSONObjMaxUserSize);
{
- // check no $ modifiers. note we only check top level. (scanning deep would be quite expensive)
BSONObjIterator i( js );
while ( i.more() ) {
BSONElement e = i.next();
- uassert( 13511 , "document to insert can't have $ fields" , e.fieldName()[0] != '$' );
+
+ // check no $ modifiers. note we only check top level.
+ // (scanning deep would be quite expensive)
+ uassert( 13511, "document to insert can't have $ fields", e.fieldName()[0] != '$' );
+
+ // check no regexp for _id (SERVER-9502)
+ if (str::equals(e.fieldName(), "_id")) {
+ uassert(16814, "can't use a regex for _id", e.type() != RegEx);
+ }
}
}
+
theDataFileMgr.insertWithObjMod(ns,
// May be modified in the call to add an _id field.
js,
diff --git a/src/mongo/db/jsobj.cpp b/src/mongo/db/jsobj.cpp
index dcb105e50ba..16659ed8cd6 100644
--- a/src/mongo/db/jsobj.cpp
+++ b/src/mongo/db/jsobj.cpp
@@ -893,6 +893,13 @@ namespace mongo {
;
}
+ // check no regexp for _id (SERVER-9502)
+ if (mongoutils::str::equals(e.fieldName(), "_id")) {
+ if (e.type() == RegEx) {
+ return false;
+ }
+ }
+
if ( e.mayEncapsulate() ) {
switch ( e.type() ) {
case Object: