Skip to content

Commit c3e9de2

Browse files
Add regression test for _array_of_documents_to_buffer bound check
Asserts an embedded-document length larger than the remaining array bytes raises InvalidBSON, and that a valid buffer still decodes.
1 parent e59a21f commit c3e9de2

1 file changed

Lines changed: 26 additions & 0 deletions

File tree

‎test/test_bson.py‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1756,6 +1756,32 @@ def test_array_of_documents_to_buffer(self):
17561756
with self.assertRaises(InvalidBSON):
17571757
_array_of_documents_to_buffer(buf)
17581758

1759+
def test_array_of_documents_to_buffer_rejects_oversized_element(self):
1760+
# Regression test for the bound check in
1761+
# _cbson_array_of_documents_to_buffer: an embedded document whose
1762+
# declared length exceeds the bytes remaining in the array document
1763+
# must raise InvalidBSON before any copy, rather than reading out of
1764+
# bounds (CWE-125).
1765+
doc = dict(a=1)
1766+
valid = encode({"0": doc})
1767+
# A well-formed buffer is unaffected by the guard.
1768+
self.assertEqual(_array_of_documents_to_buffer(valid), encode(doc))
1769+
# The first embedded document starts after the array header:
1770+
# 4-byte array length + 1-byte element type (0x03) + "0\x00" key = 7.
1771+
# Its leading 4 bytes are the embedded document's declared length.
1772+
offset = 4 + 1 + 2
1773+
malformed = bytearray(valid)
1774+
# Claim a length far larger than what remains (but >= BSON_MIN_SIZE so
1775+
# the existing lower-bound check still passes), forcing the new
1776+
# upper-bound guard to reject it.
1777+
malformed[offset:offset + 4] = struct.pack("<i", 0x7FFF)
1778+
# The C fast-path raises a dedicated "invalid array content" error from the
1779+
# new bound check; the pure-Python path reaches the same invariant through
1780+
# _get_object_size, which raises "invalid object length".
1781+
expected = "invalid array content" if bson.has_c() else "invalid object length"
1782+
with self.assertRaisesRegex(InvalidBSON, expected):
1783+
_array_of_documents_to_buffer(bytes(malformed))
1784+
17591785

17601786
class TestLongLongToString(unittest.TestCase):
17611787
def test_long_long_to_string(self):

0 commit comments

Comments
 (0)