diff options
author | Eric Milkie <milkie@10gen.com> | 2013-05-13 17:25:41 -0400 |
---|---|---|
committer | Eric Milkie <milkie@10gen.com> | 2013-05-15 14:26:44 -0400 |
commit | 7030cc8148131c8ac4910dd316929019f1909468 (patch) | |
tree | e9a3a9a42a93b677796f5e40173dc25b087dd309 | |
parent | b4c5ac3579fff46b19b927bf4a51b11cb262fc3a (diff) | |
download | mongo-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.js | 19 | ||||
-rw-r--r-- | src/mongo/db/instance.cpp | 12 | ||||
-rw-r--r-- | src/mongo/db/jsobj.cpp | 7 |
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: |