File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 1818#define PY_SSIZE_T_CLEAN
1919#include "Python.h"
2020
21+ #include <limits.h>
2122#include <stdlib.h>
2223#include <string.h>
2324
@@ -105,18 +106,25 @@ static int buffer_grow(buffer_t buffer, int min_length) {
105106 * Return non-zero and sets MemoryError on allocation failure.
106107 * Return non-zero and sets ValueError if `size` would exceed 2GiB. */
107108static int buffer_assure_space (buffer_t buffer , int size ) {
108- int new_size = buffer -> position + size ;
109- /* Check for overflow. */
110- if (new_size < buffer -> position ) {
109+ long long new_size ;
110+ if (size < 0 ) {
111111 PyErr_SetString (PyExc_ValueError ,
112112 "Document would overflow BSON size limit" );
113113 return 1 ;
114114 }
115115
116- if (new_size <= buffer -> size ) {
116+ /* Compute in a wider type so the addition cannot overflow `int`. */
117+ new_size = (long long )buffer -> position + (long long )size ;
118+ if (new_size > INT_MAX ) {
119+ PyErr_SetString (PyExc_ValueError ,
120+ "Document would overflow BSON size limit" );
121+ return 1 ;
122+ }
123+
124+ if ((int )new_size <= buffer -> size ) {
117125 return 0 ;
118126 }
119- return buffer_grow (buffer , new_size );
127+ return buffer_grow (buffer , ( int ) new_size );
120128}
121129
122130/* Save `size` bytes from the current position in `buffer` (and grow if needed).
Original file line number Diff line number Diff line change @@ -691,6 +691,14 @@ def test_overflow(self):
691691 self .assertTrue (encode ({"x" : - 9223372036854775808 }))
692692 self .assertRaises (OverflowError , encode , {"x" : - 9223372036854775809 })
693693
694+ @unittest .skipUnless (bson .has_c (), "This test requires the C extension" )
695+ def test_encode_size_limit (self ):
696+ # PYTHON-5996: encoding must raise when a document's encoded size
697+ # exceeds the BSON size limit.
698+ big_value = "a" * (1 << 30 )
699+ with self .assertRaises (ValueError ):
700+ encode ({"a" : big_value , "b" : big_value , "c" : big_value })
701+
694702 def test_small_long_encode_decode (self ):
695703 encoded1 = encode ({"x" : 256 })
696704 decoded1 = decode (encoded1 )["x" ]
You can’t perform that action at this time.
0 commit comments