Merge tag 'perf-tools-for-v6.5-2-2023-07-06' of git://git.kernel.org/pub/scm/linux...
[platform/kernel/linux-starfive.git] / lib / strcat_kunit.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Kernel module for testing 'strcat' family of functions.
4  */
5
6 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
7
8 #include <kunit/test.h>
9 #include <linux/string.h>
10
11 static volatile int unconst;
12
13 static void strcat_test(struct kunit *test)
14 {
15         char dest[8];
16
17         /* Destination is terminated. */
18         memset(dest, 0, sizeof(dest));
19         KUNIT_EXPECT_EQ(test, strlen(dest), 0);
20         /* Empty copy does nothing. */
21         KUNIT_EXPECT_TRUE(test, strcat(dest, "") == dest);
22         KUNIT_EXPECT_STREQ(test, dest, "");
23         /* 4 characters copied in, stops at %NUL. */
24         KUNIT_EXPECT_TRUE(test, strcat(dest, "four\000123") == dest);
25         KUNIT_EXPECT_STREQ(test, dest, "four");
26         KUNIT_EXPECT_EQ(test, dest[5], '\0');
27         /* 2 more characters copied in okay. */
28         KUNIT_EXPECT_TRUE(test, strcat(dest, "AB") == dest);
29         KUNIT_EXPECT_STREQ(test, dest, "fourAB");
30 }
31
32 static void strncat_test(struct kunit *test)
33 {
34         char dest[8];
35
36         /* Destination is terminated. */
37         memset(dest, 0, sizeof(dest));
38         KUNIT_EXPECT_EQ(test, strlen(dest), 0);
39         /* Empty copy of size 0 does nothing. */
40         KUNIT_EXPECT_TRUE(test, strncat(dest, "", 0 + unconst) == dest);
41         KUNIT_EXPECT_STREQ(test, dest, "");
42         /* Empty copy of size 1 does nothing too. */
43         KUNIT_EXPECT_TRUE(test, strncat(dest, "", 1 + unconst) == dest);
44         KUNIT_EXPECT_STREQ(test, dest, "");
45         /* Copy of max 0 characters should do nothing. */
46         KUNIT_EXPECT_TRUE(test, strncat(dest, "asdf", 0 + unconst) == dest);
47         KUNIT_EXPECT_STREQ(test, dest, "");
48
49         /* 4 characters copied in, even if max is 8. */
50         KUNIT_EXPECT_TRUE(test, strncat(dest, "four\000123", 8 + unconst) == dest);
51         KUNIT_EXPECT_STREQ(test, dest, "four");
52         KUNIT_EXPECT_EQ(test, dest[5], '\0');
53         KUNIT_EXPECT_EQ(test, dest[6], '\0');
54         /* 2 characters copied in okay, 2 ignored. */
55         KUNIT_EXPECT_TRUE(test, strncat(dest, "ABCD", 2 + unconst) == dest);
56         KUNIT_EXPECT_STREQ(test, dest, "fourAB");
57 }
58
59 static void strlcat_test(struct kunit *test)
60 {
61         char dest[8] = "";
62         int len = sizeof(dest) + unconst;
63
64         /* Destination is terminated. */
65         KUNIT_EXPECT_EQ(test, strlen(dest), 0);
66         /* Empty copy is size 0. */
67         KUNIT_EXPECT_EQ(test, strlcat(dest, "", len), 0);
68         KUNIT_EXPECT_STREQ(test, dest, "");
69         /* Size 1 should keep buffer terminated, report size of source only. */
70         KUNIT_EXPECT_EQ(test, strlcat(dest, "four", 1 + unconst), 4);
71         KUNIT_EXPECT_STREQ(test, dest, "");
72
73         /* 4 characters copied in. */
74         KUNIT_EXPECT_EQ(test, strlcat(dest, "four", len), 4);
75         KUNIT_EXPECT_STREQ(test, dest, "four");
76         /* 2 characters copied in okay, gets to 6 total. */
77         KUNIT_EXPECT_EQ(test, strlcat(dest, "AB", len), 6);
78         KUNIT_EXPECT_STREQ(test, dest, "fourAB");
79         /* 2 characters ignored if max size (7) reached. */
80         KUNIT_EXPECT_EQ(test, strlcat(dest, "CD", 7 + unconst), 8);
81         KUNIT_EXPECT_STREQ(test, dest, "fourAB");
82         /* 1 of 2 characters skipped, now at true max size. */
83         KUNIT_EXPECT_EQ(test, strlcat(dest, "EFG", len), 9);
84         KUNIT_EXPECT_STREQ(test, dest, "fourABE");
85         /* Everything else ignored, now at full size. */
86         KUNIT_EXPECT_EQ(test, strlcat(dest, "1234", len), 11);
87         KUNIT_EXPECT_STREQ(test, dest, "fourABE");
88 }
89
90 static struct kunit_case strcat_test_cases[] = {
91         KUNIT_CASE(strcat_test),
92         KUNIT_CASE(strncat_test),
93         KUNIT_CASE(strlcat_test),
94         {}
95 };
96
97 static struct kunit_suite strcat_test_suite = {
98         .name = "strcat",
99         .test_cases = strcat_test_cases,
100 };
101
102 kunit_test_suite(strcat_test_suite);
103
104 MODULE_LICENSE("GPL");