PYTHON-623: do not allow sending _ids with a key starting with $

This commit is contained in:
Kyle Erf 2014-01-14 02:19:03 -05:00 committed by Bernie Hackett
parent 35246a9040
commit e100ddcb20
3 changed files with 12 additions and 5 deletions

View File

@ -477,10 +477,12 @@ def _dict_to_bson(dict, check_keys, uuid_subtype, top_level=True):
try:
elements = []
if top_level and "_id" in dict:
elements.append(_element_to_bson("_id", dict["_id"], False, uuid_subtype))
elements.append(_element_to_bson("_id", dict["_id"],
check_keys, uuid_subtype))
for (key, value) in dict.iteritems():
if not top_level or key != "_id":
elements.append(_element_to_bson(key, value, check_keys, uuid_subtype))
elements.append(_element_to_bson(key, value,
check_keys, uuid_subtype))
except AttributeError:
raise TypeError("encoder expected a mapping type but got: %r" % dict)

View File

@ -1341,9 +1341,8 @@ int write_dict(PyObject* self, buffer_t buffer,
if (top_level) {
PyObject* _id = PyDict_GetItemString(dict, "_id");
if (_id) {
/* Don't bother checking keys, but do make sure we're allowed to
* write _id */
if (!write_pair(self, buffer, "_id", 3, _id, 0, uuid_subtype, 1)) {
if (!write_pair(self, buffer, "_id", 3,
_id, check_keys, uuid_subtype, 1)) {
return 0;
}
}

View File

@ -676,6 +676,12 @@ class TestBSON(unittest.TestCase):
self.assertTrue(Timestamp(1, 0) <= Timestamp(1, 0))
self.assertFalse(Timestamp(1, 0) > Timestamp(1, 0))
def test_bad_id_keys(self):
self.assertRaises(InvalidDocument, BSON.encode,
{"_id": {"$bad": 123}}, True)
self.assertRaises(InvalidDocument, BSON.encode,
{"_id": {'$oid': "52d0b971b3ba219fdeb4170e"}}, True)
BSON.encode({"_id": {'$oid': "52d0b971b3ba219fdeb4170e"}})
if __name__ == "__main__":
unittest.main()