Commit | Line | Data |
---|---|---|
3bf301e1 KC |
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"); |