Skip to content

Commit 3a08d9a

Browse files
committed
CXX-518 don't allow sending _id with nested $ key
1 parent ae293a2 commit 3a08d9a

File tree

3 files changed

+58
-3
lines changed

3 files changed

+58
-3
lines changed

src/mongo/SConscript

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,15 @@ unittests = [
5353
'base/parse_number_test',
5454
'bson/bson_field_test',
5555
'bson/bson_obj_test',
56-
'bson/oid_test',
5756
'bson/bson_validate_test',
5857
'bson/bsonobjbuilder_test',
59-
'bson/util/builder_test',
58+
'bson/oid_test',
6059
'bson/util/bson_extract_test',
60+
'bson/util/builder_test',
6161
'client/connection_string_test',
6262
'client/dbclient_rs_test',
6363
'client/index_spec_test',
64+
'client/insert_write_operation_test',
6465
'client/replica_set_monitor_test',
6566
'client/write_concern_test',
6667
'db/dbmessage_test',

src/mongo/client/insert_write_operation.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#include "mongo/client/insert_write_operation.h"
1919

20+
#include "mongo/bson/bsontypes.h"
2021
#include "mongo/client/dbclientinterface.h"
2122
#include "mongo/db/namespace_string.h"
2223

@@ -66,8 +67,11 @@ namespace mongo {
6667
}
6768

6869
BSONObj InsertWriteOperation::_ensureId(const BSONObj& doc) {
69-
if (doc.hasField("_id"))
70+
BSONElement id = doc.getField("_id");
71+
if (!id.eoo()) {
72+
uassert(0, "value of _id element cannot contain any fields starting with $", !id.isABSONObj() || id.Obj().okForStorage());
7073
return doc;
74+
}
7175

7276
BSONObjBuilder bob;
7377
bob.append("_id", OID::gen());
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/* Copyright 2015 MongoDB Inc.
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
#include "mongo/client/insert_write_operation.h"
17+
18+
#include "mongo/bson/bsonobj.h"
19+
#include "mongo/bson/bsonobjbuilder.h"
20+
#include "mongo/util/assert_util.h"
21+
22+
#include "mongo/unittest/unittest.h"
23+
24+
namespace {
25+
26+
using namespace mongo;
27+
28+
TEST(InsertWriteOperation, IdFieldCannotContainDollarSignTopLevel) {
29+
BSONObjBuilder bob;
30+
bob.append("foo", "bar");
31+
BSONObjBuilder subbob(bob.subobjStart("_id"));
32+
subbob.append("$bad", "nogood");
33+
subbob.done();
34+
ASSERT_THROWS(InsertWriteOperation w(bob.done()), UserException);
35+
}
36+
37+
TEST(InsertWriteOperation, IdFieldCannotContainDollarSignNested) {
38+
BSONObjBuilder bob;
39+
bob.append("garply", "nnnnoooo");
40+
BSONObjBuilder subbob(bob.subobjStart("_id"));
41+
BSONObjBuilder subsubbob(subbob.subobjStart("foo"));
42+
BSONObjBuilder subsubsubbob(subbob.subobjStart("baz"));
43+
subsubsubbob.append("$blah", "borked");
44+
subsubsubbob.done();
45+
subsubbob.done();
46+
subbob.done();
47+
ASSERT_THROWS(InsertWriteOperation w(bob.done()), UserException);
48+
}
49+
50+
} // namespace

0 commit comments

Comments
 (0)