Skip to content

Commit dc94ca6

Browse files
PYTHON-2361 Support parsing as extended JSON representation for subtype 4 binary (#483)
1 parent 963759a commit dc94ca6

File tree

11 files changed

+67
-18
lines changed

11 files changed

+67
-18
lines changed

bson/json_util.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,8 @@ def _parse_legacy_uuid(doc, json_options):
508508
"""Decode a JSON legacy $uuid to Python UUID."""
509509
if len(doc) != 1:
510510
raise TypeError('Bad $uuid, extra field(s): %s' % (doc,))
511+
if not isinstance(doc["$uuid"], text_type):
512+
raise TypeError('$uuid must be a string: %s' % (doc,))
511513
if json_options.uuid_representation == UuidRepresentation.UNSPECIFIED:
512514
return Binary.from_uuid(uuid.UUID(doc["$uuid"]))
513515
else:

test/bson_corpus/array.json

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,22 @@
1414
"canonical_extjson": "{\"a\" : [{\"$numberInt\": \"10\"}]}"
1515
},
1616
{
17-
"description": "Single Element Array with index set incorrectly",
17+
"description": "Single Element Array with index set incorrectly to empty string",
1818
"degenerate_bson": "130000000461000B00000010000A0000000000",
1919
"canonical_bson": "140000000461000C0000001030000A0000000000",
2020
"canonical_extjson": "{\"a\" : [{\"$numberInt\": \"10\"}]}"
2121
},
2222
{
23-
"description": "Single Element Array with index set incorrectly",
23+
"description": "Single Element Array with index set incorrectly to ab",
2424
"degenerate_bson": "150000000461000D000000106162000A0000000000",
2525
"canonical_bson": "140000000461000C0000001030000A0000000000",
2626
"canonical_extjson": "{\"a\" : [{\"$numberInt\": \"10\"}]}"
27+
},
28+
{
29+
"description": "Multi Element Array with duplicate indexes",
30+
"degenerate_bson": "1b000000046100130000001030000a000000103000140000000000",
31+
"canonical_bson": "1b000000046100130000001030000a000000103100140000000000",
32+
"canonical_extjson": "{\"a\" : [{\"$numberInt\": \"10\"}, {\"$numberInt\": \"20\"}]}"
2733
}
2834
],
2935
"decodeErrors": [

test/bson_corpus/binary.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@
3939
"canonical_bson": "1D000000057800100000000473FFD26444B34C6990E8E7D1DFC035D400",
4040
"canonical_extjson": "{\"x\" : { \"$binary\" : {\"base64\" : \"c//SZESzTGmQ6OfR38A11A==\", \"subType\" : \"04\"}}}"
4141
},
42+
{
43+
"description": "subtype 0x04 UUID",
44+
"canonical_bson": "1D000000057800100000000473FFD26444B34C6990E8E7D1DFC035D400",
45+
"canonical_extjson": "{\"x\" : { \"$binary\" : {\"base64\" : \"c//SZESzTGmQ6OfR38A11A==\", \"subType\" : \"04\"}}}",
46+
"degenerate_extjson": "{\"x\" : { \"$uuid\" : \"73ffd264-44b3-4c69-90e8-e7d1dfc035d4\"}}"
47+
},
4248
{
4349
"description": "subtype 0x05",
4450
"canonical_bson": "1D000000057800100000000573FFD26444B34C6990E8E7D1DFC035D400",
@@ -81,5 +87,15 @@
8187
"description": "subtype 0x02 length negative one",
8288
"bson": "130000000578000600000002FFFFFFFFFFFF00"
8389
}
90+
],
91+
"parseErrors": [
92+
{
93+
"description": "$uuid wrong type",
94+
"string": "{\"x\" : { \"$uuid\" : { \"data\" : \"73ffd264-44b3-4c69-90e8-e7d1dfc035d4\"}}}"
95+
},
96+
{
97+
"description": "$uuid invalid value",
98+
"string": "{\"x\" : { \"$uuid\" : \"73ffd264-44b3-90e8-e7d1dfc035d4\"}}"
99+
}
84100
]
85101
}

test/bson_corpus/datetime.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@
2525
"description" : "Y10K",
2626
"canonical_bson" : "1000000009610000DC1FD277E6000000",
2727
"canonical_extjson" : "{\"a\":{\"$date\":{\"$numberLong\":\"253402300800000\"}}}"
28+
},
29+
{
30+
"description": "leading zero ms",
31+
"canonical_bson": "10000000096100D1D6D6CC3B01000000",
32+
"relaxed_extjson": "{\"a\" : {\"$date\" : \"2012-12-24T12:15:30.001Z\"}}",
33+
"canonical_extjson": "{\"a\" : {\"$date\" : {\"$numberLong\" : \"1356351330001\"}}}"
2834
}
2935
],
3036
"decodeErrors": [

test/bson_corpus/decimal128-2.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -790,3 +790,4 @@
790790
}
791791
]
792792
}
793+

test/bson_corpus/decimal128-5.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,3 +399,4 @@
399399
}
400400
]
401401
}
402+

test/bson_corpus/double.json

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,16 @@
2828
"relaxed_extjson": "{\"d\" : -1.0001220703125}"
2929
},
3030
{
31-
"description": "1.2345678901234568e+18",
32-
"canonical_bson": "1000000001640081E97DF41022B14300",
33-
"canonical_extjson": "{\"d\" : {\"$numberDouble\": \"1.2345678901234568e+18\"}}",
34-
"relaxed_extjson": "{\"d\" : 1.2345678901234568E+18}"
31+
"description": "1.2345678921232E+18",
32+
"canonical_bson": "100000000164002a1bf5f41022b14300",
33+
"canonical_extjson": "{\"d\" : {\"$numberDouble\": \"1.2345678921232e+18\"}}",
34+
"relaxed_extjson": "{\"d\" : 1.2345678921232E+18}"
3535
},
3636
{
37-
"description": "-1.2345678901234568e+18",
38-
"canonical_bson": "1000000001640081E97DF41022B1C300",
39-
"canonical_extjson": "{\"d\" : {\"$numberDouble\": \"-1.2345678901234568e+18\"}}",
40-
"relaxed_extjson": "{\"d\" : -1.2345678901234568e+18}"
37+
"description": "-1.2345678921232E+18",
38+
"canonical_bson": "100000000164002a1bf5f41022b1c300",
39+
"canonical_extjson": "{\"d\" : {\"$numberDouble\": \"-1.2345678921232e+18\"}}",
40+
"relaxed_extjson": "{\"d\" : -1.2345678921232E+18}"
4141
},
4242
{
4343
"description": "0.0",

test/bson_corpus/multi-type-deprecated.json

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@
55
"valid": [
66
{
77
"description": "All BSON types",
8-
"canonical_bson": "3B020000075F69640057E193D7A9CC81B4027498B50E53796D626F6C000700000073796D626F6C0002537472696E670007000000737472696E670010496E743332002A00000012496E743634002A0000000000000001446F75626C6500000000000000F0BF0542696E617279001000000003A34C38F7C3ABEDC8A37814A992AB8DB60542696E61727955736572446566696E656400050000008001020304050D436F6465000E00000066756E6374696F6E2829207B7D000F436F64655769746853636F7065001B0000000E00000066756E6374696F6E2829207B7D00050000000003537562646F63756D656E74001200000002666F6F0004000000626172000004417272617900280000001030000100000010310002000000103200030000001033000400000010340005000000001154696D657374616D7000010000002A0000000B5265676578007061747465726E0000094461746574696D6545706F6368000000000000000000094461746574696D65506F73697469766500FFFFFF7F00000000094461746574696D654E656761746976650000000080FFFFFFFF085472756500010846616C736500000C4442506F696E746572000E00000064622E636F6C6C656374696F6E0057E193D7A9CC81B4027498B1034442526566003D0000000224726566000B000000636F6C6C656374696F6E00072469640057FD71E96E32AB4225B723FB02246462000900000064617461626173650000FF4D696E6B6579007F4D61786B6579000A4E756C6C0006556E646566696E65640000",
9-
"converted_bson": "4b020000075f69640057e193d7a9cc81b4027498b50253796d626f6c000700000073796d626f6c0002537472696e670007000000737472696e670010496e743332002a00000012496e743634002a0000000000000001446f75626c6500000000000000f0bf0542696e617279001000000003a34c38f7c3abedc8a37814a992ab8db60542696e61727955736572446566696e656400050000008001020304050d436f6465000e00000066756e6374696f6e2829207b7d000f436f64655769746853636f7065001b0000000e00000066756e6374696f6e2829207b7d00050000000003537562646f63756d656e74001200000002666f6f0004000000626172000004417272617900280000001030000100000010310002000000103200030000001033000400000010340005000000001154696d657374616d7000010000002a0000000b5265676578007061747465726e0000094461746574696d6545706f6368000000000000000000094461746574696d65506f73697469766500ffffff7f00000000094461746574696d654e656761746976650000000080ffffffff085472756500010846616c73650000034442506f696e746572002e0000000224726566000e00000064622e636f6c6c656374696f6e00072469640057e193d7a9cc81b4027498b100034442526566003d0000000224726566000b000000636f6c6c656374696f6e00072469640057fd71e96e32ab4225b723fb02246462000900000064617461626173650000ff4d696e6b6579007f4d61786b6579000a4e756c6c000a556e646566696e65640000",
10-
"canonical_extjson": "{\"_id\": {\"$oid\": \"57e193d7a9cc81b4027498b5\"}, \"Symbol\": {\"$symbol\": \"symbol\"}, \"String\": \"string\", \"Int32\": {\"$numberInt\": \"42\"}, \"Int64\": {\"$numberLong\": \"42\"}, \"Double\": {\"$numberDouble\": \"-1.0\"}, \"Binary\": { \"$binary\" : {\"base64\": \"o0w498Or7cijeBSpkquNtg==\", \"subType\": \"03\"}}, \"BinaryUserDefined\": { \"$binary\" : {\"base64\": \"AQIDBAU=\", \"subType\": \"80\"}}, \"Code\": {\"$code\": \"function() {}\"}, \"CodeWithScope\": {\"$code\": \"function() {}\", \"$scope\": {}}, \"Subdocument\": {\"foo\": \"bar\"}, \"Array\": [{\"$numberInt\": \"1\"}, {\"$numberInt\": \"2\"}, {\"$numberInt\": \"3\"}, {\"$numberInt\": \"4\"}, {\"$numberInt\": \"5\"}], \"Timestamp\": {\"$timestamp\": {\"t\": 42, \"i\": 1}}, \"Regex\": {\"$regularExpression\": {\"pattern\": \"pattern\", \"options\": \"\"}}, \"DatetimeEpoch\": {\"$date\": {\"$numberLong\": \"0\"}}, \"DatetimePositive\": {\"$date\": {\"$numberLong\": \"2147483647\"}}, \"DatetimeNegative\": {\"$date\": {\"$numberLong\": \"-2147483648\"}}, \"True\": true, \"False\": false, \"DBPointer\": {\"$dbPointer\": {\"$ref\": \"db.collection\", \"$id\": {\"$oid\": \"57e193d7a9cc81b4027498b1\"}}}, \"DBRef\": {\"$ref\": \"collection\", \"$id\": {\"$oid\": \"57fd71e96e32ab4225b723fb\"}, \"$db\": \"database\"}, \"Minkey\": {\"$minKey\": 1}, \"Maxkey\": {\"$maxKey\": 1}, \"Null\": null, \"Undefined\": {\"$undefined\": true}}",
11-
"converted_extjson": "{\"_id\": {\"$oid\": \"57e193d7a9cc81b4027498b5\"}, \"Symbol\": \"symbol\", \"String\": \"string\", \"Int32\": {\"$numberInt\": \"42\"}, \"Int64\": {\"$numberLong\": \"42\"}, \"Double\": {\"$numberDouble\": \"-1.0\"}, \"Binary\": { \"$binary\" : {\"base64\": \"o0w498Or7cijeBSpkquNtg==\", \"subType\": \"03\"}}, \"BinaryUserDefined\": { \"$binary\" : {\"base64\": \"AQIDBAU=\", \"subType\": \"80\"}}, \"Code\": {\"$code\": \"function() {}\"}, \"CodeWithScope\": {\"$code\": \"function() {}\", \"$scope\": {}}, \"Subdocument\": {\"foo\": \"bar\"}, \"Array\": [{\"$numberInt\": \"1\"}, {\"$numberInt\": \"2\"}, {\"$numberInt\": \"3\"}, {\"$numberInt\": \"4\"}, {\"$numberInt\": \"5\"}], \"Timestamp\": {\"$timestamp\": {\"t\": 42, \"i\": 1}}, \"Regex\": {\"$regularExpression\": {\"pattern\": \"pattern\", \"options\": \"\"}}, \"DatetimeEpoch\": {\"$date\": {\"$numberLong\": \"0\"}}, \"DatetimePositive\": {\"$date\": {\"$numberLong\": \"2147483647\"}}, \"DatetimeNegative\": {\"$date\": {\"$numberLong\": \"-2147483648\"}}, \"True\": true, \"False\": false, \"DBPointer\": {\"$ref\": \"db.collection\", \"$id\": {\"$oid\": \"57e193d7a9cc81b4027498b1\"}}, \"DBRef\": {\"$ref\": \"collection\", \"$id\": {\"$oid\": \"57fd71e96e32ab4225b723fb\"}, \"$db\": \"database\"}, \"Minkey\": {\"$minKey\": 1}, \"Maxkey\": {\"$maxKey\": 1}, \"Null\": null, \"Undefined\": null}"
8+
"canonical_bson": "38020000075F69640057E193D7A9CC81B4027498B50E53796D626F6C000700000073796D626F6C0002537472696E670007000000737472696E670010496E743332002A00000012496E743634002A0000000000000001446F75626C6500000000000000F0BF0542696E617279001000000003A34C38F7C3ABEDC8A37814A992AB8DB60542696E61727955736572446566696E656400050000008001020304050D436F6465000E00000066756E6374696F6E2829207B7D000F436F64655769746853636F7065001B0000000E00000066756E6374696F6E2829207B7D00050000000003537562646F63756D656E74001200000002666F6F0004000000626172000004417272617900280000001030000100000010310002000000103200030000001033000400000010340005000000001154696D657374616D7000010000002A0000000B5265676578007061747465726E0000094461746574696D6545706F6368000000000000000000094461746574696D65506F73697469766500FFFFFF7F00000000094461746574696D654E656761746976650000000080FFFFFFFF085472756500010846616C736500000C4442506F696E746572000B000000636F6C6C656374696F6E0057E193D7A9CC81B4027498B1034442526566003D0000000224726566000B000000636F6C6C656374696F6E00072469640057FD71E96E32AB4225B723FB02246462000900000064617461626173650000FF4D696E6B6579007F4D61786B6579000A4E756C6C0006556E646566696E65640000",
9+
"converted_bson": "48020000075f69640057e193d7a9cc81b4027498b50253796d626f6c000700000073796d626f6c0002537472696e670007000000737472696e670010496e743332002a00000012496e743634002a0000000000000001446f75626c6500000000000000f0bf0542696e617279001000000003a34c38f7c3abedc8a37814a992ab8db60542696e61727955736572446566696e656400050000008001020304050d436f6465000e00000066756e6374696f6e2829207b7d000f436f64655769746853636f7065001b0000000e00000066756e6374696f6e2829207b7d00050000000003537562646f63756d656e74001200000002666f6f0004000000626172000004417272617900280000001030000100000010310002000000103200030000001033000400000010340005000000001154696d657374616d7000010000002a0000000b5265676578007061747465726e0000094461746574696d6545706f6368000000000000000000094461746574696d65506f73697469766500ffffff7f00000000094461746574696d654e656761746976650000000080ffffffff085472756500010846616c73650000034442506f696e746572002b0000000224726566000b000000636f6c6c656374696f6e00072469640057e193d7a9cc81b4027498b100034442526566003d0000000224726566000b000000636f6c6c656374696f6e00072469640057fd71e96e32ab4225b723fb02246462000900000064617461626173650000ff4d696e6b6579007f4d61786b6579000a4e756c6c000a556e646566696e65640000",
10+
"canonical_extjson": "{\"_id\": {\"$oid\": \"57e193d7a9cc81b4027498b5\"}, \"Symbol\": {\"$symbol\": \"symbol\"}, \"String\": \"string\", \"Int32\": {\"$numberInt\": \"42\"}, \"Int64\": {\"$numberLong\": \"42\"}, \"Double\": {\"$numberDouble\": \"-1.0\"}, \"Binary\": { \"$binary\" : {\"base64\": \"o0w498Or7cijeBSpkquNtg==\", \"subType\": \"03\"}}, \"BinaryUserDefined\": { \"$binary\" : {\"base64\": \"AQIDBAU=\", \"subType\": \"80\"}}, \"Code\": {\"$code\": \"function() {}\"}, \"CodeWithScope\": {\"$code\": \"function() {}\", \"$scope\": {}}, \"Subdocument\": {\"foo\": \"bar\"}, \"Array\": [{\"$numberInt\": \"1\"}, {\"$numberInt\": \"2\"}, {\"$numberInt\": \"3\"}, {\"$numberInt\": \"4\"}, {\"$numberInt\": \"5\"}], \"Timestamp\": {\"$timestamp\": {\"t\": 42, \"i\": 1}}, \"Regex\": {\"$regularExpression\": {\"pattern\": \"pattern\", \"options\": \"\"}}, \"DatetimeEpoch\": {\"$date\": {\"$numberLong\": \"0\"}}, \"DatetimePositive\": {\"$date\": {\"$numberLong\": \"2147483647\"}}, \"DatetimeNegative\": {\"$date\": {\"$numberLong\": \"-2147483648\"}}, \"True\": true, \"False\": false, \"DBPointer\": {\"$dbPointer\": {\"$ref\": \"collection\", \"$id\": {\"$oid\": \"57e193d7a9cc81b4027498b1\"}}}, \"DBRef\": {\"$ref\": \"collection\", \"$id\": {\"$oid\": \"57fd71e96e32ab4225b723fb\"}, \"$db\": \"database\"}, \"Minkey\": {\"$minKey\": 1}, \"Maxkey\": {\"$maxKey\": 1}, \"Null\": null, \"Undefined\": {\"$undefined\": true}}",
11+
"converted_extjson": "{\"_id\": {\"$oid\": \"57e193d7a9cc81b4027498b5\"}, \"Symbol\": \"symbol\", \"String\": \"string\", \"Int32\": {\"$numberInt\": \"42\"}, \"Int64\": {\"$numberLong\": \"42\"}, \"Double\": {\"$numberDouble\": \"-1.0\"}, \"Binary\": { \"$binary\" : {\"base64\": \"o0w498Or7cijeBSpkquNtg==\", \"subType\": \"03\"}}, \"BinaryUserDefined\": { \"$binary\" : {\"base64\": \"AQIDBAU=\", \"subType\": \"80\"}}, \"Code\": {\"$code\": \"function() {}\"}, \"CodeWithScope\": {\"$code\": \"function() {}\", \"$scope\": {}}, \"Subdocument\": {\"foo\": \"bar\"}, \"Array\": [{\"$numberInt\": \"1\"}, {\"$numberInt\": \"2\"}, {\"$numberInt\": \"3\"}, {\"$numberInt\": \"4\"}, {\"$numberInt\": \"5\"}], \"Timestamp\": {\"$timestamp\": {\"t\": 42, \"i\": 1}}, \"Regex\": {\"$regularExpression\": {\"pattern\": \"pattern\", \"options\": \"\"}}, \"DatetimeEpoch\": {\"$date\": {\"$numberLong\": \"0\"}}, \"DatetimePositive\": {\"$date\": {\"$numberLong\": \"2147483647\"}}, \"DatetimeNegative\": {\"$date\": {\"$numberLong\": \"-2147483648\"}}, \"True\": true, \"False\": false, \"DBPointer\": {\"$ref\": \"collection\", \"$id\": {\"$oid\": \"57e193d7a9cc81b4027498b1\"}}, \"DBRef\": {\"$ref\": \"collection\", \"$id\": {\"$oid\": \"57fd71e96e32ab4225b723fb\"}, \"$db\": \"database\"}, \"Minkey\": {\"$minKey\": 1}, \"Maxkey\": {\"$maxKey\": 1}, \"Null\": null, \"Undefined\": null}"
1212
}
1313
]
1414
}
15+

test/bson_corpus/timestamp.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@
1818
"description": "Timestamp with high-order bit set on both seconds and increment",
1919
"canonical_bson": "10000000116100FFFFFFFFFFFFFFFF00",
2020
"canonical_extjson": "{\"a\" : {\"$timestamp\" : {\"t\" : 4294967295, \"i\" : 4294967295} } }"
21+
},
22+
{
23+
"description": "Timestamp with high-order bit set on both seconds and increment (not UINT32_MAX)",
24+
"canonical_bson": "1000000011610000286BEE00286BEE00",
25+
"canonical_extjson": "{\"a\" : {\"$timestamp\" : {\"t\" : 4000000000, \"i\" : 4000000000} } }"
2126
}
2227
],
2328
"decodeErrors": [

test/bson_corpus/top.json

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,11 +69,11 @@
6969
"parseErrors": [
7070
{
7171
"description" : "Bad $regularExpression (extra field)",
72-
"string" : "{\"a\" : \"$regularExpression\": {\"pattern\": \"abc\", \"options\": \"\", \"unrelated\": true}}}"
72+
"string" : "{\"a\" : {\"$regularExpression\": {\"pattern\": \"abc\", \"options\": \"\", \"unrelated\": true}}}"
7373
},
7474
{
7575
"description" : "Bad $regularExpression (missing options field)",
76-
"string" : "{\"a\" : \"$regularExpression\": {\"pattern\": \"abc\"}}}"
76+
"string" : "{\"a\" : {\"$regularExpression\": {\"pattern\": \"abc\"}}}"
7777
},
7878
{
7979
"description": "Bad $regularExpression (pattern is number, not string)",
@@ -85,7 +85,7 @@
8585
},
8686
{
8787
"description" : "Bad $regularExpression (missing pattern field)",
88-
"string" : "{\"a\" : \"$regularExpression\": {\"options\":\"ix\"}}}"
88+
"string" : "{\"a\" : {\"$regularExpression\": {\"options\":\"ix\"}}}"
8989
},
9090
{
9191
"description": "Bad $oid (number, not string)",
@@ -151,6 +151,10 @@
151151
"description": "Bad $code (type is number, not string)",
152152
"string": "{\"a\" : {\"$code\" : 42}}"
153153
},
154+
{
155+
"description": "Bad $code (type is number, not string) when $scope is also present",
156+
"string": "{\"a\" : {\"$code\" : 42, \"$scope\" : {}}}"
157+
},
154158
{
155159
"description": "Bad $code (extra field)",
156160
"string": "{\"a\" : {\"$code\" : \"\", \"unrelated\": true}}"

test/test_bson_corpus.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ def run_test(self):
115115
continue
116116

117117
# Special case for testing encoding UUID as binary subtype 0x04.
118-
if description == 'subtype 0x04':
118+
if description.startswith('subtype 0x04'):
119119
encode_extjson = to_extjson_uuid_04
120120
encode_bson = to_bson_uuid_04
121121
else:
@@ -203,6 +203,13 @@ def run_test(self):
203203
'case: ' + description)
204204
except (ValueError, KeyError, TypeError, InvalidId):
205205
pass
206+
elif bson_type == '0x05':
207+
try:
208+
decode_extjson(parse_error_case['string'])
209+
raise AssertionError('exception not raised for test '
210+
'case: ' + description)
211+
except (TypeError, ValueError):
212+
pass
206213
else:
207214
raise AssertionError('cannot test parseErrors for type ' +
208215
bson_type)

0 commit comments

Comments
 (0)