PYTHON-4084 Fix BSON inflation for RawBSONDocument (#1456)
This commit is contained in:
parent
8422edf3ab
commit
568a3b1294
@ -1878,19 +1878,8 @@ static PyObject* get_value(PyObject* self, PyObject* name, const char* buffer,
|
||||
goto invalid;
|
||||
}
|
||||
|
||||
if (options->is_raw_bson) {
|
||||
value = PyObject_CallFunction(
|
||||
options->document_class, "y#O",
|
||||
buffer + *position, (Py_ssize_t)size, options->options_obj);
|
||||
if (!value) {
|
||||
goto invalid;
|
||||
}
|
||||
*position += size;
|
||||
break;
|
||||
}
|
||||
|
||||
value = elements_to_dict(self, buffer + *position + 4,
|
||||
size - 5, options);
|
||||
value = elements_to_dict(self, buffer + *position,
|
||||
size, options);
|
||||
if (!value) {
|
||||
goto invalid;
|
||||
}
|
||||
@ -2456,8 +2445,8 @@ static PyObject* get_value(PyObject* self, PyObject* name, const char* buffer,
|
||||
if (buffer[*position + scope_size - 1]) {
|
||||
goto invalid;
|
||||
}
|
||||
scope = elements_to_dict(self, buffer + *position + 4,
|
||||
scope_size - 5, options);
|
||||
scope = elements_to_dict(self, buffer + *position,
|
||||
scope_size, options);
|
||||
if (!scope) {
|
||||
Py_DECREF(code);
|
||||
goto invalid;
|
||||
@ -2809,9 +2798,14 @@ static PyObject* elements_to_dict(PyObject* self, const char* string,
|
||||
unsigned max,
|
||||
const codec_options_t* options) {
|
||||
PyObject* result;
|
||||
if (options->is_raw_bson) {
|
||||
return PyObject_CallFunction(
|
||||
options->document_class, "y#O",
|
||||
string, max, options->options_obj);
|
||||
}
|
||||
if (Py_EnterRecursiveCall(" while decoding a BSON document"))
|
||||
return NULL;
|
||||
result = _elements_to_dict(self, string, max, options);
|
||||
result = _elements_to_dict(self, string + 4, max - 5, options);
|
||||
Py_LeaveRecursiveCall();
|
||||
return result;
|
||||
}
|
||||
@ -2902,15 +2896,7 @@ static PyObject* _cbson_bson_to_dict(PyObject* self, PyObject* args) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* No need to decode fields if using RawBSONDocument */
|
||||
if (options.is_raw_bson) {
|
||||
result = PyObject_CallFunction(
|
||||
options.document_class, "y#O", string, (Py_ssize_t)size,
|
||||
options_obj);
|
||||
}
|
||||
else {
|
||||
result = elements_to_dict(self, string + 4, (unsigned)size - 5, &options);
|
||||
}
|
||||
result = elements_to_dict(self, string, (unsigned)size, &options);
|
||||
done:
|
||||
PyBuffer_Release(&view);
|
||||
destroy_codec_options(&options);
|
||||
@ -2988,14 +2974,7 @@ static PyObject* _cbson_decode_all(PyObject* self, PyObject* args) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* No need to decode fields if using RawBSONDocument. */
|
||||
if (options.is_raw_bson) {
|
||||
dict = PyObject_CallFunction(
|
||||
options.document_class, "y#O", string, (Py_ssize_t)size,
|
||||
options_obj);
|
||||
} else {
|
||||
dict = elements_to_dict(self, string + 4, (unsigned)size - 5, &options);
|
||||
}
|
||||
dict = elements_to_dict(self, string, (unsigned)size, &options);
|
||||
if (!dict) {
|
||||
Py_DECREF(result);
|
||||
goto fail;
|
||||
|
||||
@ -10,6 +10,7 @@ PyMongo 4.7 brings a number of improvements including:
|
||||
:attr:`pymongo.monitoring.CommandStartedEvent.server_connection_id`,
|
||||
:attr:`pymongo.monitoring.CommandSucceededEvent.server_connection_id`, and
|
||||
:attr:`pymongo.monitoring.CommandFailedEvent.server_connection_id` properties.
|
||||
- Fixed a bug where inflating a :class:`~bson.raw_bson.RawBSONDocument` containing a :class:`~bson.code.Code` would cause an error.
|
||||
|
||||
Changes in Version 4.6.1
|
||||
------------------------
|
||||
|
||||
@ -22,7 +22,7 @@ sys.path[0:0] = [""]
|
||||
from test import client_context, unittest
|
||||
from test.test_client import IntegrationTest
|
||||
|
||||
from bson import decode, encode
|
||||
from bson import Code, decode, encode
|
||||
from bson.binary import JAVA_LEGACY, Binary, UuidRepresentation
|
||||
from bson.codec_options import CodecOptions
|
||||
from bson.errors import InvalidBSON
|
||||
@ -199,6 +199,12 @@ class TestRawBSONDocument(IntegrationTest):
|
||||
for rkey, elt in zip(rawdoc, keyvaluepairs):
|
||||
self.assertEqual(rkey, elt[0])
|
||||
|
||||
def test_contains_code_with_scope(self):
|
||||
doc = RawBSONDocument(encode({"value": Code("x=1", scope={})}))
|
||||
|
||||
self.assertEqual(decode(encode(doc)), {"value": Code("x=1", {})})
|
||||
self.assertEqual(doc["value"].scope, RawBSONDocument(encode({})))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
Loading…
Reference in New Issue
Block a user