@@ -445,6 +445,85 @@ static void test_strscpy(struct kunit *test)
445445 KUNIT_EXPECT_EQ (test , strscpy (dest , "This is too long" , ARRAY_SIZE (dest )), - E2BIG );
446446}
447447
448+ static volatile int unconst ;
449+
450+ static void test_strcat (struct kunit * test )
451+ {
452+ char dest [8 ];
453+
454+ /* Destination is terminated. */
455+ memset (dest , 0 , sizeof (dest ));
456+ KUNIT_EXPECT_EQ (test , strlen (dest ), 0 );
457+ /* Empty copy does nothing. */
458+ KUNIT_EXPECT_TRUE (test , strcat (dest , "" ) == dest );
459+ KUNIT_EXPECT_STREQ (test , dest , "" );
460+ /* 4 characters copied in, stops at %NUL. */
461+ KUNIT_EXPECT_TRUE (test , strcat (dest , "four\000123" ) == dest );
462+ KUNIT_EXPECT_STREQ (test , dest , "four" );
463+ KUNIT_EXPECT_EQ (test , dest [5 ], '\0' );
464+ /* 2 more characters copied in okay. */
465+ KUNIT_EXPECT_TRUE (test , strcat (dest , "AB" ) == dest );
466+ KUNIT_EXPECT_STREQ (test , dest , "fourAB" );
467+ }
468+
469+ static void test_strncat (struct kunit * test )
470+ {
471+ char dest [8 ];
472+
473+ /* Destination is terminated. */
474+ memset (dest , 0 , sizeof (dest ));
475+ KUNIT_EXPECT_EQ (test , strlen (dest ), 0 );
476+ /* Empty copy of size 0 does nothing. */
477+ KUNIT_EXPECT_TRUE (test , strncat (dest , "" , 0 + unconst ) == dest );
478+ KUNIT_EXPECT_STREQ (test , dest , "" );
479+ /* Empty copy of size 1 does nothing too. */
480+ KUNIT_EXPECT_TRUE (test , strncat (dest , "" , 1 + unconst ) == dest );
481+ KUNIT_EXPECT_STREQ (test , dest , "" );
482+ /* Copy of max 0 characters should do nothing. */
483+ KUNIT_EXPECT_TRUE (test , strncat (dest , "asdf" , 0 + unconst ) == dest );
484+ KUNIT_EXPECT_STREQ (test , dest , "" );
485+
486+ /* 4 characters copied in, even if max is 8. */
487+ KUNIT_EXPECT_TRUE (test , strncat (dest , "four\000123" , 8 + unconst ) == dest );
488+ KUNIT_EXPECT_STREQ (test , dest , "four" );
489+ KUNIT_EXPECT_EQ (test , dest [5 ], '\0' );
490+ KUNIT_EXPECT_EQ (test , dest [6 ], '\0' );
491+ /* 2 characters copied in okay, 2 ignored. */
492+ KUNIT_EXPECT_TRUE (test , strncat (dest , "ABCD" , 2 + unconst ) == dest );
493+ KUNIT_EXPECT_STREQ (test , dest , "fourAB" );
494+ }
495+
496+ static void test_strlcat (struct kunit * test )
497+ {
498+ char dest [8 ] = "" ;
499+ int len = sizeof (dest ) + unconst ;
500+
501+ /* Destination is terminated. */
502+ KUNIT_EXPECT_EQ (test , strlen (dest ), 0 );
503+ /* Empty copy is size 0. */
504+ KUNIT_EXPECT_EQ (test , strlcat (dest , "" , len ), 0 );
505+ KUNIT_EXPECT_STREQ (test , dest , "" );
506+ /* Size 1 should keep buffer terminated, report size of source only. */
507+ KUNIT_EXPECT_EQ (test , strlcat (dest , "four" , 1 + unconst ), 4 );
508+ KUNIT_EXPECT_STREQ (test , dest , "" );
509+
510+ /* 4 characters copied in. */
511+ KUNIT_EXPECT_EQ (test , strlcat (dest , "four" , len ), 4 );
512+ KUNIT_EXPECT_STREQ (test , dest , "four" );
513+ /* 2 characters copied in okay, gets to 6 total. */
514+ KUNIT_EXPECT_EQ (test , strlcat (dest , "AB" , len ), 6 );
515+ KUNIT_EXPECT_STREQ (test , dest , "fourAB" );
516+ /* 2 characters ignored if max size (7) reached. */
517+ KUNIT_EXPECT_EQ (test , strlcat (dest , "CD" , 7 + unconst ), 8 );
518+ KUNIT_EXPECT_STREQ (test , dest , "fourAB" );
519+ /* 1 of 2 characters skipped, now at true max size. */
520+ KUNIT_EXPECT_EQ (test , strlcat (dest , "EFG" , len ), 9 );
521+ KUNIT_EXPECT_STREQ (test , dest , "fourABE" );
522+ /* Everything else ignored, now at full size. */
523+ KUNIT_EXPECT_EQ (test , strlcat (dest , "1234" , len ), 11 );
524+ KUNIT_EXPECT_STREQ (test , dest , "fourABE" );
525+ }
526+
448527static struct kunit_case string_test_cases [] = {
449528 KUNIT_CASE (test_memset16 ),
450529 KUNIT_CASE (test_memset32 ),
@@ -461,6 +540,9 @@ static struct kunit_case string_test_cases[] = {
461540 KUNIT_CASE (test_strncasecmp ),
462541 KUNIT_CASE (test_strncasecmp_long_strings ),
463542 KUNIT_CASE (test_strscpy ),
543+ KUNIT_CASE (test_strcat ),
544+ KUNIT_CASE (test_strncat ),
545+ KUNIT_CASE (test_strlcat ),
464546 {}
465547};
466548
0 commit comments