@@ -304,6 +304,61 @@ test_bson_strcasecmp (void)
304
304
BSON_ASSERT (bson_strcasecmp ("FoZ" , "foo" ) > 0 );
305
305
}
306
306
307
+ static void
308
+ test_bson_string_truncate (void )
309
+ {
310
+ // Test truncating.
311
+ {
312
+ bson_string_t * str = bson_string_new ("foobar" );
313
+ ASSERT_CMPSIZE_T (str -> len , = = , 6u );
314
+ ASSERT_CMPSIZE_T (str -> alloc , = = , 8u );
315
+
316
+ bson_string_truncate (str , 2 );
317
+ ASSERT_CMPSTR (str -> str , "fo" );
318
+ ASSERT_CMPSIZE_T (str -> len , = = , 2u );
319
+ ASSERT_CMPSIZE_T (str -> alloc , = = , 4u );
320
+ bson_string_free (str , true);
321
+ }
322
+
323
+ // Test truncating to same length.
324
+ {
325
+ bson_string_t * str = bson_string_new ("foobar" );
326
+ ASSERT_CMPSIZE_T (str -> len , = = , 6u );
327
+ ASSERT_CMPSIZE_T (str -> alloc , = = , 8u );
328
+
329
+ bson_string_truncate (str , 6u );
330
+ ASSERT_CMPSTR (str -> str , "foobar" );
331
+ ASSERT_CMPUINT32 (str -> len , = = , 6u );
332
+ ASSERT_CMPSIZE_T (str -> alloc , = = , 8u );
333
+ bson_string_free (str , true);
334
+ }
335
+
336
+ // Test truncating to 0.
337
+ {
338
+ bson_string_t * str = bson_string_new ("foobar" );
339
+ ASSERT_CMPSIZE_T (str -> len , = = , 6u );
340
+ ASSERT_CMPSIZE_T (str -> alloc , = = , 8u );
341
+
342
+ bson_string_truncate (str , 0u );
343
+ ASSERT_CMPSTR (str -> str , "" );
344
+ ASSERT_CMPUINT32 (str -> len , = = , 0u );
345
+ ASSERT_CMPSIZE_T (str -> alloc , = = , 1u );
346
+ bson_string_free (str , true);
347
+ }
348
+
349
+ // Test truncating beyond string length.
350
+ // The documentation for `bson_string_truncate` says the truncated length "must be smaller or equal to the current
351
+ // length of the string.". However, `bson_string_truncate` does not reject greater lengths. For backwards
352
+ // compatibility, this behavior is preserved.
353
+ {
354
+ bson_string_t * str = bson_string_new ("a" );
355
+ bson_string_truncate (str , 2u ); // Is not rejected.
356
+ ASSERT_CMPUINT32 (str -> len , = = , 2u );
357
+ ASSERT_CMPUINT32 (str -> alloc , = = , 4u );
358
+ bson_string_free (str , true);
359
+ }
360
+ }
361
+
307
362
static void
308
363
test_bson_string_capacity (void * unused )
309
364
{
@@ -356,6 +411,16 @@ test_bson_string_capacity (void *unused)
356
411
large_str [UINT32_MAX - 2u ] = 's' ; // Restore.
357
412
}
358
413
414
+ // Can truncate strings of length close to UINT32_MAX - 1.
415
+ {
416
+ large_str [UINT32_MAX - 1u ] = '\0' ; // Set size.
417
+ bson_string_t * str = bson_string_new (large_str );
418
+ bson_string_truncate (str , UINT32_MAX - 2 ); // Truncate one character.
419
+ ASSERT_CMPSIZE_T (strlen (str -> str ), = = , UINT32_MAX - 2u );
420
+ bson_string_free (str , true);
421
+ large_str [UINT32_MAX - 1u ] = 's' ; // Restore.
422
+ }
423
+
359
424
bson_free (large_str );
360
425
}
361
426
@@ -385,4 +450,5 @@ test_string_install (TestSuite *suite)
385
450
TestSuite_Add (suite , "/bson/string/strcasecmp" , test_bson_strcasecmp );
386
451
TestSuite_AddFull (
387
452
suite , "/bson/string/capacity" , test_bson_string_capacity , NULL , NULL , skip_if_no_large_allocations );
453
+ TestSuite_Add (suite , "/bson/string/truncate" , test_bson_string_truncate );
388
454
}
0 commit comments