@@ -1384,6 +1384,213 @@ test_bson_vector_example_packed_bit_view (void)
1384
1384
bson_destroy (& doc );
1385
1385
}
1386
1386
1387
+ static void
1388
+ test_bson_vector_edge_cases_int8 (void )
1389
+ {
1390
+ size_t max_representable_elements = (size_t ) UINT32_MAX - BSON_VECTOR_HEADER_LEN ;
1391
+
1392
+ // Test binary_data_length (uint32_t) edge cases, without any allocation.
1393
+ {
1394
+ ASSERT_CMPUINT32 (bson_vector_int8_binary_data_length (max_representable_elements - 1u ), = = , UINT32_MAX - 1u );
1395
+ ASSERT_CMPUINT32 (bson_vector_int8_binary_data_length (max_representable_elements ), = = , UINT32_MAX );
1396
+ ASSERT_CMPUINT32 (bson_vector_int8_binary_data_length (max_representable_elements + 1u ), = = , 0 );
1397
+ }
1398
+
1399
+ // Needs little real memory because most bytes are never accessed,
1400
+ // but we do need a virtual address space larger than 32 bits.
1401
+ #if BSON_WORD_SIZE > 32
1402
+
1403
+ size_t expected_bson_overhead =
1404
+ 5 /* empty bson document */ + 3 /* "v" element header */ + 5 /* binary item header */ ;
1405
+ size_t max_alloc_elements = (size_t ) BSON_MAX_SIZE - expected_bson_overhead - BSON_VECTOR_HEADER_LEN ;
1406
+
1407
+ bson_t doc = BSON_INITIALIZER ;
1408
+ bson_vector_int8_view_t view ;
1409
+
1410
+ // Test allocation (BSON_MAX_SIZE + uint32_t) edge cases.
1411
+ {
1412
+ ASSERT (!BSON_APPEND_VECTOR_INT8_UNINIT (& doc , "v" , max_representable_elements , & view ));
1413
+ ASSERT (!BSON_APPEND_VECTOR_INT8_UNINIT (& doc , "v" , max_representable_elements + 1u , & view ));
1414
+ ASSERT (!BSON_APPEND_VECTOR_INT8_UNINIT (& doc , "v" , max_alloc_elements + 1u , & view ));
1415
+ ASSERT (BSON_APPEND_VECTOR_INT8_UNINIT (& doc , "v" , max_alloc_elements , & view ));
1416
+ }
1417
+
1418
+ // Test some read and write boundaries.
1419
+ {
1420
+ int8_t values [] = {1 , 2 , 3 , 4 , 5 };
1421
+ size_t values_size = sizeof values / sizeof values [0 ];
1422
+ ASSERT (bson_vector_int8_view_write (view , values , values_size , 0 ));
1423
+ ASSERT (bson_vector_int8_view_read (view , values , values_size , 0 ));
1424
+ ASSERT (!bson_vector_int8_view_write (view , values , max_alloc_elements + 1u , 0 ));
1425
+ ASSERT (!bson_vector_int8_view_read (view , values , max_alloc_elements + 1u , 0 ));
1426
+ ASSERT (bson_vector_int8_view_write (view , values , values_size , max_alloc_elements - values_size ));
1427
+ ASSERT (bson_vector_int8_view_read (view , values , values_size , max_alloc_elements - values_size ));
1428
+ ASSERT (!bson_vector_int8_view_write (view , values , values_size , max_alloc_elements - values_size + 1u ));
1429
+ ASSERT (!bson_vector_int8_view_read (view , values , values_size , max_alloc_elements - values_size + 1u ));
1430
+ ASSERT (!bson_vector_int8_view_write (view , values , values_size + 1u , max_alloc_elements - values_size ));
1431
+ ASSERT (!bson_vector_int8_view_read (view , values , values_size + 1u , max_alloc_elements - values_size ));
1432
+ ASSERT (!bson_vector_int8_view_write (view , values , SIZE_MAX , max_alloc_elements - values_size ));
1433
+ ASSERT (!bson_vector_int8_view_read (view , values , SIZE_MAX , max_alloc_elements - values_size ));
1434
+ ASSERT (!bson_vector_int8_view_write (view , values , SIZE_MAX , max_alloc_elements - values_size + 1u ));
1435
+ ASSERT (!bson_vector_int8_view_read (view , values , SIZE_MAX , max_alloc_elements - values_size + 1u ));
1436
+ }
1437
+
1438
+ bson_destroy (& doc );
1439
+ #endif // BSON_WORD_SIZE > 32
1440
+ }
1441
+
1442
+ static void
1443
+ test_bson_vector_edge_cases_float32 (void )
1444
+ {
1445
+ size_t max_representable_elements = ((size_t ) UINT32_MAX - BSON_VECTOR_HEADER_LEN ) / sizeof (float );
1446
+
1447
+ // Test binary_data_length (uint32_t) edge cases, without any allocation.
1448
+ // Note that the longest possible multiple of a complete element is 1 byte short of UINT32_MAX.
1449
+ {
1450
+ ASSERT_CMPUINT32 (
1451
+ bson_vector_float32_binary_data_length (max_representable_elements - 1u ), = = , UINT32_MAX - 1u - 4u );
1452
+ ASSERT_CMPUINT32 (bson_vector_float32_binary_data_length (max_representable_elements ), = = , UINT32_MAX - 1u );
1453
+ ASSERT_CMPUINT32 (bson_vector_float32_binary_data_length (max_representable_elements + 1u ), = = , 0 );
1454
+ }
1455
+
1456
+ // Needs little real memory because most bytes are never accessed,
1457
+ // but we do need a virtual address space larger than 32 bits.
1458
+ #if BSON_WORD_SIZE > 32
1459
+
1460
+ size_t expected_bson_overhead =
1461
+ 5 /* empty bson document */ + 3 /* "v" element header */ + 5 /* binary item header */ ;
1462
+ size_t max_alloc_elements =
1463
+ ((size_t ) BSON_MAX_SIZE - expected_bson_overhead - BSON_VECTOR_HEADER_LEN ) / sizeof (float );
1464
+
1465
+ bson_t doc = BSON_INITIALIZER ;
1466
+ bson_vector_float32_view_t view ;
1467
+
1468
+ // Test allocation (BSON_MAX_SIZE + uint32_t) edge cases.
1469
+ {
1470
+ ASSERT (!BSON_APPEND_VECTOR_FLOAT32_UNINIT (& doc , "v" , max_representable_elements , & view ));
1471
+ ASSERT (!BSON_APPEND_VECTOR_FLOAT32_UNINIT (& doc , "v" , max_representable_elements + 1u , & view ));
1472
+ ASSERT (!BSON_APPEND_VECTOR_FLOAT32_UNINIT (& doc , "v" , max_alloc_elements + 1u , & view ));
1473
+ ASSERT (BSON_APPEND_VECTOR_FLOAT32_UNINIT (& doc , "v" , max_alloc_elements , & view ));
1474
+ }
1475
+
1476
+ // Test some read and write boundaries.
1477
+ {
1478
+ float values [] = {1.f , 2.f , 3.f , 4.f , 5.f };
1479
+ size_t values_size = sizeof values / sizeof values [0 ];
1480
+ ASSERT (bson_vector_float32_view_write (view , values , values_size , 0 ));
1481
+ ASSERT (bson_vector_float32_view_read (view , values , values_size , 0 ));
1482
+ ASSERT (!bson_vector_float32_view_write (view , values , max_alloc_elements + 1u , 0 ));
1483
+ ASSERT (!bson_vector_float32_view_read (view , values , max_alloc_elements + 1u , 0 ));
1484
+ ASSERT (bson_vector_float32_view_write (view , values , values_size , max_alloc_elements - values_size ));
1485
+ ASSERT (bson_vector_float32_view_read (view , values , values_size , max_alloc_elements - values_size ));
1486
+ ASSERT (!bson_vector_float32_view_write (view , values , values_size , max_alloc_elements - values_size + 1u ));
1487
+ ASSERT (!bson_vector_float32_view_read (view , values , values_size , max_alloc_elements - values_size + 1u ));
1488
+ ASSERT (!bson_vector_float32_view_write (view , values , values_size + 1u , max_alloc_elements - values_size ));
1489
+ ASSERT (!bson_vector_float32_view_read (view , values , values_size + 1u , max_alloc_elements - values_size ));
1490
+ ASSERT (!bson_vector_float32_view_write (view , values , SIZE_MAX , max_alloc_elements - values_size ));
1491
+ ASSERT (!bson_vector_float32_view_read (view , values , SIZE_MAX , max_alloc_elements - values_size ));
1492
+ ASSERT (!bson_vector_float32_view_write (view , values , SIZE_MAX , max_alloc_elements - values_size + 1u ));
1493
+ ASSERT (!bson_vector_float32_view_read (view , values , SIZE_MAX , max_alloc_elements - values_size + 1u ));
1494
+ }
1495
+
1496
+ bson_destroy (& doc );
1497
+ #endif // BSON_WORD_SIZE > 32
1498
+ }
1499
+
1500
+ static void
1501
+ test_bson_vector_edge_cases_packed_bit (void )
1502
+ {
1503
+ size_t max_representable_elements = ((size_t ) UINT32_MAX - BSON_VECTOR_HEADER_LEN ) * 8u ;
1504
+
1505
+ // Test binary_data_length (uint32_t) edge cases, without any allocation.
1506
+ {
1507
+ ASSERT_CMPUINT32 (
1508
+ bson_vector_packed_bit_binary_data_length (max_representable_elements - 8u ), = = , UINT32_MAX - 1u );
1509
+ ASSERT_CMPUINT32 (bson_vector_packed_bit_binary_data_length (max_representable_elements - 7u ), = = , UINT32_MAX );
1510
+ ASSERT_CMPUINT32 (bson_vector_packed_bit_binary_data_length (max_representable_elements ), = = , UINT32_MAX );
1511
+ ASSERT_CMPUINT32 (bson_vector_packed_bit_binary_data_length (max_representable_elements + 1u ), = = , 0 );
1512
+ }
1513
+
1514
+ // Needs little real memory because most bytes are never accessed,
1515
+ // but we do need a virtual address space larger than 32 bits.
1516
+ #if BSON_WORD_SIZE > 32
1517
+
1518
+ size_t expected_bson_overhead =
1519
+ 5 /* empty bson document */ + 3 /* "v" element header */ + 5 /* binary item header */ ;
1520
+ size_t max_alloc_bytes = (size_t ) BSON_MAX_SIZE - expected_bson_overhead - BSON_VECTOR_HEADER_LEN ;
1521
+ size_t max_alloc_elements = max_alloc_bytes * 8u ;
1522
+
1523
+ bson_t doc = BSON_INITIALIZER ;
1524
+ bson_vector_packed_bit_view_t view ;
1525
+
1526
+ // Test allocation (BSON_MAX_SIZE + uint32_t) edge cases.
1527
+ {
1528
+ ASSERT (!BSON_APPEND_VECTOR_PACKED_BIT_UNINIT (& doc , "v" , max_representable_elements , & view ));
1529
+ ASSERT (!BSON_APPEND_VECTOR_PACKED_BIT_UNINIT (& doc , "v" , max_representable_elements + 1u , & view ));
1530
+ ASSERT (!BSON_APPEND_VECTOR_PACKED_BIT_UNINIT (& doc , "v" , max_alloc_elements + 1u , & view ));
1531
+ ASSERT (BSON_APPEND_VECTOR_PACKED_BIT_UNINIT (& doc , "v" , max_alloc_elements , & view ));
1532
+ }
1533
+
1534
+ // Test some pack and unpack boundaries, similar to the read/write tests for non-packed element types.
1535
+ // Only tests one length, but it's chosen to be greater than 8 and not a multiple of 8.
1536
+ {
1537
+ bool values [190 ];
1538
+ size_t values_size = sizeof values / sizeof values [0 ];
1539
+ for (size_t i = 0 ; i < values_size ; i ++ ) {
1540
+ values [i ] = (i & 3 ) == 3 ;
1541
+ }
1542
+ ASSERT (bson_vector_packed_bit_view_pack_bool (view , values , values_size , 0 ));
1543
+ ASSERT (bson_vector_packed_bit_view_unpack_bool (view , values , values_size , 0 ));
1544
+ ASSERT (!bson_vector_packed_bit_view_pack_bool (view , values , max_alloc_elements + 1u , 0 ));
1545
+ ASSERT (!bson_vector_packed_bit_view_unpack_bool (view , values , max_alloc_elements + 1u , 0 ));
1546
+ ASSERT (bson_vector_packed_bit_view_pack_bool (view , values , values_size , max_alloc_elements - values_size ));
1547
+ ASSERT (bson_vector_packed_bit_view_unpack_bool (view , values , values_size , max_alloc_elements - values_size ));
1548
+ ASSERT (
1549
+ !bson_vector_packed_bit_view_pack_bool (view , values , values_size , max_alloc_elements - values_size + 1u ));
1550
+ ASSERT (
1551
+ !bson_vector_packed_bit_view_unpack_bool (view , values , values_size , max_alloc_elements - values_size + 1u ));
1552
+ ASSERT (
1553
+ !bson_vector_packed_bit_view_pack_bool (view , values , values_size + 1u , max_alloc_elements - values_size ));
1554
+ ASSERT (
1555
+ !bson_vector_packed_bit_view_unpack_bool (view , values , values_size + 1u , max_alloc_elements - values_size ));
1556
+ ASSERT (!bson_vector_packed_bit_view_pack_bool (view , values , SIZE_MAX , max_alloc_elements - values_size ));
1557
+ ASSERT (!bson_vector_packed_bit_view_unpack_bool (view , values , SIZE_MAX , max_alloc_elements - values_size ));
1558
+ ASSERT (!bson_vector_packed_bit_view_pack_bool (view , values , SIZE_MAX , max_alloc_elements - values_size + 1u ));
1559
+ ASSERT (!bson_vector_packed_bit_view_unpack_bool (view , values , SIZE_MAX , max_alloc_elements - values_size + 1u ));
1560
+ }
1561
+
1562
+ // Test some read and write boundaries on packed bytes.
1563
+ {
1564
+ uint8_t packed [] = {0x12 , 0x34 , 0x56 , 0x78 , 0x9A };
1565
+ ASSERT (bson_vector_packed_bit_view_write_packed (view , packed , sizeof packed , 0 ));
1566
+ ASSERT (bson_vector_packed_bit_view_read_packed (view , packed , sizeof packed , 0 ));
1567
+ ASSERT (!bson_vector_packed_bit_view_write_packed (view , packed , max_alloc_bytes + 1u , 0 ));
1568
+ ASSERT (!bson_vector_packed_bit_view_read_packed (view , packed , max_alloc_bytes + 1u , 0 ));
1569
+ ASSERT (
1570
+ bson_vector_packed_bit_view_write_packed (view , packed , sizeof packed , max_alloc_bytes - sizeof packed ));
1571
+ ASSERT (
1572
+ bson_vector_packed_bit_view_read_packed (view , packed , sizeof packed , max_alloc_bytes - sizeof packed ));
1573
+ ASSERT (!bson_vector_packed_bit_view_write_packed (
1574
+ view , packed , sizeof packed , max_alloc_bytes - sizeof packed + 1u ));
1575
+ ASSERT (!bson_vector_packed_bit_view_read_packed (
1576
+ view , packed , sizeof packed , max_alloc_bytes - sizeof packed + 1u ));
1577
+ ASSERT (!bson_vector_packed_bit_view_write_packed (
1578
+ view , packed , sizeof packed + 1u , max_alloc_bytes - sizeof packed ));
1579
+ ASSERT (!bson_vector_packed_bit_view_read_packed (
1580
+ view , packed , sizeof packed + 1u , max_alloc_bytes - sizeof packed ));
1581
+ ASSERT (
1582
+ !bson_vector_packed_bit_view_write_packed (view , packed , SIZE_MAX , max_alloc_bytes - sizeof packed ));
1583
+ ASSERT (!bson_vector_packed_bit_view_read_packed (view , packed , SIZE_MAX , max_alloc_bytes - sizeof packed ));
1584
+ ASSERT (!bson_vector_packed_bit_view_write_packed (
1585
+ view , packed , SIZE_MAX , max_alloc_bytes - sizeof packed + 1u ));
1586
+ ASSERT (
1587
+ !bson_vector_packed_bit_view_read_packed (view , packed , SIZE_MAX , max_alloc_bytes - sizeof packed + 1u ));
1588
+ }
1589
+
1590
+ bson_destroy (& doc );
1591
+ #endif // BSON_WORD_SIZE > 32
1592
+ }
1593
+
1387
1594
void
1388
1595
test_bson_vector_install (TestSuite * suite )
1389
1596
{
@@ -1404,4 +1611,8 @@ test_bson_vector_install (TestSuite *suite)
1404
1611
TestSuite_Add (
1405
1612
suite , "/bson_binary_vector/example/packed_bit_const_view" , test_bson_vector_example_packed_bit_const_view );
1406
1613
TestSuite_Add (suite , "/bson_binary_vector/example/packed_bit_view" , test_bson_vector_example_packed_bit_view );
1614
+
1615
+ TestSuite_Add (suite , "/bson_binary_vector/edge_cases/int8" , test_bson_vector_edge_cases_int8 );
1616
+ TestSuite_Add (suite , "/bson_binary_vector/edge_cases/float32" , test_bson_vector_edge_cases_float32 );
1617
+ TestSuite_Add (suite , "/bson_binary_vector/edge_cases/packed_bit" , test_bson_vector_edge_cases_packed_bit );
1407
1618
}
0 commit comments