@@ -1756,6 +1756,28 @@ 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+ with self .assertRaises (InvalidBSON ):
1779+ _array_of_documents_to_buffer (bytes (malformed ))
1780+
17591781
17601782class TestLongLongToString (unittest .TestCase ):
17611783 def test_long_long_to_string (self ):
0 commit comments