@@ -1264,45 +1264,109 @@ test_bson_init_static (void)
12641264 bson_destroy (& b );
12651265}
12661266
1267+ static void *
1268+ realloc_func_never_called (void * mem , size_t num_bytes , void * ctx )
1269+ {
1270+ // Reallocate function for tests that should never reallocate
1271+ BSON_UNUSED (num_bytes );
1272+ BSON_UNUSED (ctx );
1273+ BSON_ASSERT (false);
1274+ return mem ;
1275+ }
12671276
12681277static void
12691278test_bson_new_from_buffer (void )
12701279{
1271- bson_t * b ;
1272- uint8_t * buf = bson_malloc0 (5 );
1273- size_t len = 5 ;
1274- uint32_t len_le = BSON_UINT32_TO_LE (5 );
1280+ // Buffer size matches document size
1281+ {
1282+ uint8_t * buf = bson_malloc0 (5 );
1283+ size_t len = 5 ;
1284+ uint32_t len_le = BSON_UINT32_TO_LE (5 );
12751285
1276- memcpy (buf , & len_le , sizeof (len_le ));
1286+ memcpy (buf , & len_le , sizeof (len_le ));
12771287
1278- b = bson_new_from_buffer (& buf , & len , bson_realloc_ctx , NULL );
1288+ bson_t * b = bson_new_from_buffer (& buf , & len , bson_realloc_ctx , NULL );
12791289
1280- BSON_ASSERT (b -> flags & BSON_FLAG_NO_FREE );
1281- BSON_ASSERT (len == 5 );
1282- BSON_ASSERT (b -> len == 5 );
1290+ BSON_ASSERT (b -> flags & BSON_FLAG_NO_FREE );
1291+ BSON_ASSERT (len == 5 );
1292+ BSON_ASSERT (b -> len == 5 );
12831293
1284- bson_append_utf8 (b , "hello" , -1 , "world" , -1 );
1294+ bson_append_utf8 (b , "hello" , -1 , "world" , -1 );
12851295
1286- BSON_ASSERT (len == 32 );
1287- BSON_ASSERT (b -> len == 22 );
1296+ BSON_ASSERT (len == 32 );
1297+ BSON_ASSERT (b -> len == 22 );
12881298
1289- bson_destroy (b );
1299+ bson_destroy (b );
1300+ BSON_ASSERT (buf );
1301+ bson_free (buf );
1302+ }
12901303
1291- bson_free (buf );
1304+ // Buffer is NULL. An empty document will be allocated.
1305+ {
1306+ uint8_t * buf = NULL ;
1307+ size_t len = 0 ;
12921308
1293- buf = NULL ;
1294- len = 0 ;
1309+ bson_t * b = bson_new_from_buffer (& buf , & len , bson_realloc_ctx , NULL );
12951310
1296- b = bson_new_from_buffer (& buf , & len , bson_realloc_ctx , NULL );
1311+ BSON_ASSERT (b -> flags & BSON_FLAG_NO_FREE );
1312+ BSON_ASSERT (len == 5 );
1313+ BSON_ASSERT (b -> len == 5 );
12971314
1298- BSON_ASSERT (b -> flags & BSON_FLAG_NO_FREE );
1299- BSON_ASSERT (len == 5 );
1300- BSON_ASSERT (b -> len == 5 );
1315+ bson_destroy (b );
1316+ BSON_ASSERT (buf );
1317+ bson_free (buf );
1318+ }
13011319
1302- bson_destroy (b );
1303- bson_free (buf );
1304- }
1320+ // Buffer is larger than the document. Expect it to be growable without reallocating.
1321+ {
1322+ size_t buf_len = 0x10000 ;
1323+ uint8_t * buf = bson_malloc0 (buf_len );
1324+ uint32_t doc_len_le = BSON_UINT32_TO_LE (5 );
1325+
1326+ memcpy (buf , & doc_len_le , sizeof (doc_len_le ));
1327+
1328+ bson_t * b = bson_new_from_buffer (& buf , & buf_len , realloc_func_never_called , NULL );
1329+
1330+ BSON_ASSERT (b -> flags & BSON_FLAG_NO_FREE );
1331+ BSON_ASSERT (buf_len == 0x10000 );
1332+ BSON_ASSERT (& buf_len == ((bson_impl_alloc_t * ) b )-> buflen );
1333+ BSON_ASSERT (b -> len == 5 );
1334+
1335+ bson_append_utf8 (b , "hello" , -1 , "world" , -1 );
13051336
1337+ BSON_ASSERT (buf_len == 0x10000 );
1338+ BSON_ASSERT (b -> len == 22 );
1339+
1340+ bson_destroy (b );
1341+ BSON_ASSERT (buf );
1342+ bson_free (buf );
1343+ }
1344+
1345+ // Otherwise valid, but buffer is smaller than the document size. bson_new_from_buffer() must fail.
1346+ {
1347+ uint8_t * buf = NULL ;
1348+ size_t buf_len = SIZE_MAX ; // Must be ignored when buf == NULL
1349+
1350+ // Start with a valid doc
1351+ bson_t * valid_doc = bson_new_from_buffer (& buf , & buf_len , bson_realloc_ctx , NULL );
1352+ BSON_ASSERT (BSON_APPEND_UTF8 (valid_doc , "hello" , "world" ));
1353+ ASSERT_CMPUINT32 (valid_doc -> len , = = , 22 );
1354+ bson_destroy (valid_doc );
1355+ ASSERT_CMPSIZE_T (buf_len , = = , 32 );
1356+
1357+ // Check that a slightly-too-small buffer is rejected
1358+ buf_len = 21 ;
1359+ BSON_ASSERT (!bson_new_from_buffer (& buf , & buf_len , realloc_func_never_called , NULL ));
1360+
1361+ // Successful return if one more byte is included in the buf_len.
1362+ buf_len ++ ;
1363+ bson_t * minimal = bson_new_from_buffer (& buf , & buf_len , realloc_func_never_called , NULL );
1364+ BSON_ASSERT (minimal != NULL );
1365+ ASSERT_CMPUINT32 (minimal -> len , = = , 22 );
1366+ bson_destroy (minimal );
1367+ bson_free (buf );
1368+ }
1369+ }
13061370
13071371static void
13081372test_bson_utf8_key (void )
0 commit comments