1*db6fe4d6SKees Cook // SPDX-License-Identifier: GPL-2.0-only
2*db6fe4d6SKees Cook /*
3*db6fe4d6SKees Cook * Test cases for string functions.
4*db6fe4d6SKees Cook */
5*db6fe4d6SKees Cook
6*db6fe4d6SKees Cook #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
7*db6fe4d6SKees Cook
8*db6fe4d6SKees Cook #include <kunit/test.h>
9*db6fe4d6SKees Cook #include <linux/module.h>
10*db6fe4d6SKees Cook #include <linux/printk.h>
11*db6fe4d6SKees Cook #include <linux/slab.h>
12*db6fe4d6SKees Cook #include <linux/string.h>
13*db6fe4d6SKees Cook
14*db6fe4d6SKees Cook #define STRCMP_LARGE_BUF_LEN 2048
15*db6fe4d6SKees Cook #define STRCMP_CHANGE_POINT 1337
16*db6fe4d6SKees Cook #define STRCMP_TEST_EXPECT_EQUAL(test, fn, ...) KUNIT_EXPECT_EQ(test, fn(__VA_ARGS__), 0)
17*db6fe4d6SKees Cook #define STRCMP_TEST_EXPECT_LOWER(test, fn, ...) KUNIT_EXPECT_LT(test, fn(__VA_ARGS__), 0)
18*db6fe4d6SKees Cook #define STRCMP_TEST_EXPECT_GREATER(test, fn, ...) KUNIT_EXPECT_GT(test, fn(__VA_ARGS__), 0)
19*db6fe4d6SKees Cook
string_test_memset16(struct kunit * test)20*db6fe4d6SKees Cook static void string_test_memset16(struct kunit *test)
21*db6fe4d6SKees Cook {
22*db6fe4d6SKees Cook unsigned i, j, k;
23*db6fe4d6SKees Cook u16 v, *p;
24*db6fe4d6SKees Cook
25*db6fe4d6SKees Cook p = kunit_kzalloc(test, 256 * 2 * 2, GFP_KERNEL);
26*db6fe4d6SKees Cook KUNIT_ASSERT_NOT_ERR_OR_NULL(test, p);
27*db6fe4d6SKees Cook
28*db6fe4d6SKees Cook for (i = 0; i < 256; i++) {
29*db6fe4d6SKees Cook for (j = 0; j < 256; j++) {
30*db6fe4d6SKees Cook memset(p, 0xa1, 256 * 2 * sizeof(v));
31*db6fe4d6SKees Cook memset16(p + i, 0xb1b2, j);
32*db6fe4d6SKees Cook for (k = 0; k < 512; k++) {
33*db6fe4d6SKees Cook v = p[k];
34*db6fe4d6SKees Cook if (k < i) {
35*db6fe4d6SKees Cook KUNIT_ASSERT_EQ_MSG(test, v, 0xa1a1,
36*db6fe4d6SKees Cook "i:%d j:%d k:%d", i, j, k);
37*db6fe4d6SKees Cook } else if (k < i + j) {
38*db6fe4d6SKees Cook KUNIT_ASSERT_EQ_MSG(test, v, 0xb1b2,
39*db6fe4d6SKees Cook "i:%d j:%d k:%d", i, j, k);
40*db6fe4d6SKees Cook } else {
41*db6fe4d6SKees Cook KUNIT_ASSERT_EQ_MSG(test, v, 0xa1a1,
42*db6fe4d6SKees Cook "i:%d j:%d k:%d", i, j, k);
43*db6fe4d6SKees Cook }
44*db6fe4d6SKees Cook }
45*db6fe4d6SKees Cook }
46*db6fe4d6SKees Cook }
47*db6fe4d6SKees Cook }
48*db6fe4d6SKees Cook
string_test_memset32(struct kunit * test)49*db6fe4d6SKees Cook static void string_test_memset32(struct kunit *test)
50*db6fe4d6SKees Cook {
51*db6fe4d6SKees Cook unsigned i, j, k;
52*db6fe4d6SKees Cook u32 v, *p;
53*db6fe4d6SKees Cook
54*db6fe4d6SKees Cook p = kunit_kzalloc(test, 256 * 2 * 4, GFP_KERNEL);
55*db6fe4d6SKees Cook KUNIT_ASSERT_NOT_ERR_OR_NULL(test, p);
56*db6fe4d6SKees Cook
57*db6fe4d6SKees Cook for (i = 0; i < 256; i++) {
58*db6fe4d6SKees Cook for (j = 0; j < 256; j++) {
59*db6fe4d6SKees Cook memset(p, 0xa1, 256 * 2 * sizeof(v));
60*db6fe4d6SKees Cook memset32(p + i, 0xb1b2b3b4, j);
61*db6fe4d6SKees Cook for (k = 0; k < 512; k++) {
62*db6fe4d6SKees Cook v = p[k];
63*db6fe4d6SKees Cook if (k < i) {
64*db6fe4d6SKees Cook KUNIT_ASSERT_EQ_MSG(test, v, 0xa1a1a1a1,
65*db6fe4d6SKees Cook "i:%d j:%d k:%d", i, j, k);
66*db6fe4d6SKees Cook } else if (k < i + j) {
67*db6fe4d6SKees Cook KUNIT_ASSERT_EQ_MSG(test, v, 0xb1b2b3b4,
68*db6fe4d6SKees Cook "i:%d j:%d k:%d", i, j, k);
69*db6fe4d6SKees Cook } else {
70*db6fe4d6SKees Cook KUNIT_ASSERT_EQ_MSG(test, v, 0xa1a1a1a1,
71*db6fe4d6SKees Cook "i:%d j:%d k:%d", i, j, k);
72*db6fe4d6SKees Cook }
73*db6fe4d6SKees Cook }
74*db6fe4d6SKees Cook }
75*db6fe4d6SKees Cook }
76*db6fe4d6SKees Cook }
77*db6fe4d6SKees Cook
string_test_memset64(struct kunit * test)78*db6fe4d6SKees Cook static void string_test_memset64(struct kunit *test)
79*db6fe4d6SKees Cook {
80*db6fe4d6SKees Cook unsigned i, j, k;
81*db6fe4d6SKees Cook u64 v, *p;
82*db6fe4d6SKees Cook
83*db6fe4d6SKees Cook p = kunit_kzalloc(test, 256 * 2 * 8, GFP_KERNEL);
84*db6fe4d6SKees Cook KUNIT_ASSERT_NOT_ERR_OR_NULL(test, p);
85*db6fe4d6SKees Cook
86*db6fe4d6SKees Cook for (i = 0; i < 256; i++) {
87*db6fe4d6SKees Cook for (j = 0; j < 256; j++) {
88*db6fe4d6SKees Cook memset(p, 0xa1, 256 * 2 * sizeof(v));
89*db6fe4d6SKees Cook memset64(p + i, 0xb1b2b3b4b5b6b7b8ULL, j);
90*db6fe4d6SKees Cook for (k = 0; k < 512; k++) {
91*db6fe4d6SKees Cook v = p[k];
92*db6fe4d6SKees Cook if (k < i) {
93*db6fe4d6SKees Cook KUNIT_ASSERT_EQ_MSG(test, v, 0xa1a1a1a1a1a1a1a1ULL,
94*db6fe4d6SKees Cook "i:%d j:%d k:%d", i, j, k);
95*db6fe4d6SKees Cook } else if (k < i + j) {
96*db6fe4d6SKees Cook KUNIT_ASSERT_EQ_MSG(test, v, 0xb1b2b3b4b5b6b7b8ULL,
97*db6fe4d6SKees Cook "i:%d j:%d k:%d", i, j, k);
98*db6fe4d6SKees Cook } else {
99*db6fe4d6SKees Cook KUNIT_ASSERT_EQ_MSG(test, v, 0xa1a1a1a1a1a1a1a1ULL,
100*db6fe4d6SKees Cook "i:%d j:%d k:%d", i, j, k);
101*db6fe4d6SKees Cook }
102*db6fe4d6SKees Cook }
103*db6fe4d6SKees Cook }
104*db6fe4d6SKees Cook }
105*db6fe4d6SKees Cook }
106*db6fe4d6SKees Cook
string_test_strchr(struct kunit * test)107*db6fe4d6SKees Cook static void string_test_strchr(struct kunit *test)
108*db6fe4d6SKees Cook {
109*db6fe4d6SKees Cook const char *test_string = "abcdefghijkl";
110*db6fe4d6SKees Cook const char *empty_string = "";
111*db6fe4d6SKees Cook char *result;
112*db6fe4d6SKees Cook int i;
113*db6fe4d6SKees Cook
114*db6fe4d6SKees Cook for (i = 0; i < strlen(test_string) + 1; i++) {
115*db6fe4d6SKees Cook result = strchr(test_string, test_string[i]);
116*db6fe4d6SKees Cook KUNIT_ASSERT_EQ_MSG(test, result - test_string, i,
117*db6fe4d6SKees Cook "char:%c", 'a' + i);
118*db6fe4d6SKees Cook }
119*db6fe4d6SKees Cook
120*db6fe4d6SKees Cook result = strchr(empty_string, '\0');
121*db6fe4d6SKees Cook KUNIT_ASSERT_PTR_EQ(test, result, empty_string);
122*db6fe4d6SKees Cook
123*db6fe4d6SKees Cook result = strchr(empty_string, 'a');
124*db6fe4d6SKees Cook KUNIT_ASSERT_NULL(test, result);
125*db6fe4d6SKees Cook
126*db6fe4d6SKees Cook result = strchr(test_string, 'z');
127*db6fe4d6SKees Cook KUNIT_ASSERT_NULL(test, result);
128*db6fe4d6SKees Cook }
129*db6fe4d6SKees Cook
string_test_strnchr(struct kunit * test)130*db6fe4d6SKees Cook static void string_test_strnchr(struct kunit *test)
131*db6fe4d6SKees Cook {
132*db6fe4d6SKees Cook const char *test_string = "abcdefghijkl";
133*db6fe4d6SKees Cook const char *empty_string = "";
134*db6fe4d6SKees Cook char *result;
135*db6fe4d6SKees Cook int i, j;
136*db6fe4d6SKees Cook
137*db6fe4d6SKees Cook for (i = 0; i < strlen(test_string) + 1; i++) {
138*db6fe4d6SKees Cook for (j = 0; j < strlen(test_string) + 2; j++) {
139*db6fe4d6SKees Cook result = strnchr(test_string, j, test_string[i]);
140*db6fe4d6SKees Cook if (j <= i) {
141*db6fe4d6SKees Cook KUNIT_ASSERT_NULL_MSG(test, result,
142*db6fe4d6SKees Cook "char:%c i:%d j:%d", 'a' + i, i, j);
143*db6fe4d6SKees Cook } else {
144*db6fe4d6SKees Cook KUNIT_ASSERT_EQ_MSG(test, result - test_string, i,
145*db6fe4d6SKees Cook "char:%c i:%d j:%d", 'a' + i, i, j);
146*db6fe4d6SKees Cook }
147*db6fe4d6SKees Cook }
148*db6fe4d6SKees Cook }
149*db6fe4d6SKees Cook
150*db6fe4d6SKees Cook result = strnchr(empty_string, 0, '\0');
151*db6fe4d6SKees Cook KUNIT_ASSERT_NULL(test, result);
152*db6fe4d6SKees Cook
153*db6fe4d6SKees Cook result = strnchr(empty_string, 1, '\0');
154*db6fe4d6SKees Cook KUNIT_ASSERT_PTR_EQ(test, result, empty_string);
155*db6fe4d6SKees Cook
156*db6fe4d6SKees Cook result = strnchr(empty_string, 1, 'a');
157*db6fe4d6SKees Cook KUNIT_ASSERT_NULL(test, result);
158*db6fe4d6SKees Cook
159*db6fe4d6SKees Cook result = strnchr(NULL, 0, '\0');
160*db6fe4d6SKees Cook KUNIT_ASSERT_NULL(test, result);
161*db6fe4d6SKees Cook }
162*db6fe4d6SKees Cook
string_test_strspn(struct kunit * test)163*db6fe4d6SKees Cook static void string_test_strspn(struct kunit *test)
164*db6fe4d6SKees Cook {
165*db6fe4d6SKees Cook static const struct strspn_test {
166*db6fe4d6SKees Cook const char str[16];
167*db6fe4d6SKees Cook const char accept[16];
168*db6fe4d6SKees Cook const char reject[16];
169*db6fe4d6SKees Cook unsigned a;
170*db6fe4d6SKees Cook unsigned r;
171*db6fe4d6SKees Cook } tests[] = {
172*db6fe4d6SKees Cook { "foobar", "", "", 0, 6 },
173*db6fe4d6SKees Cook { "abba", "abc", "ABBA", 4, 4 },
174*db6fe4d6SKees Cook { "abba", "a", "b", 1, 1 },
175*db6fe4d6SKees Cook { "", "abc", "abc", 0, 0},
176*db6fe4d6SKees Cook };
177*db6fe4d6SKees Cook const struct strspn_test *s = tests;
178*db6fe4d6SKees Cook size_t i;
179*db6fe4d6SKees Cook
180*db6fe4d6SKees Cook for (i = 0; i < ARRAY_SIZE(tests); ++i, ++s) {
181*db6fe4d6SKees Cook KUNIT_ASSERT_EQ_MSG(test, s->a, strspn(s->str, s->accept),
182*db6fe4d6SKees Cook "i:%zu", i);
183*db6fe4d6SKees Cook KUNIT_ASSERT_EQ_MSG(test, s->r, strcspn(s->str, s->reject),
184*db6fe4d6SKees Cook "i:%zu", i);
185*db6fe4d6SKees Cook }
186*db6fe4d6SKees Cook }
187*db6fe4d6SKees Cook
188*db6fe4d6SKees Cook static char strcmp_buffer1[STRCMP_LARGE_BUF_LEN];
189*db6fe4d6SKees Cook static char strcmp_buffer2[STRCMP_LARGE_BUF_LEN];
190*db6fe4d6SKees Cook
strcmp_fill_buffers(char fill1,char fill2)191*db6fe4d6SKees Cook static void strcmp_fill_buffers(char fill1, char fill2)
192*db6fe4d6SKees Cook {
193*db6fe4d6SKees Cook memset(strcmp_buffer1, fill1, STRCMP_LARGE_BUF_LEN);
194*db6fe4d6SKees Cook memset(strcmp_buffer2, fill2, STRCMP_LARGE_BUF_LEN);
195*db6fe4d6SKees Cook strcmp_buffer1[STRCMP_LARGE_BUF_LEN - 1] = 0;
196*db6fe4d6SKees Cook strcmp_buffer2[STRCMP_LARGE_BUF_LEN - 1] = 0;
197*db6fe4d6SKees Cook }
198*db6fe4d6SKees Cook
string_test_strcmp(struct kunit * test)199*db6fe4d6SKees Cook static void string_test_strcmp(struct kunit *test)
200*db6fe4d6SKees Cook {
201*db6fe4d6SKees Cook /* Equal strings */
202*db6fe4d6SKees Cook STRCMP_TEST_EXPECT_EQUAL(test, strcmp, "Hello, Kernel!", "Hello, Kernel!");
203*db6fe4d6SKees Cook /* First string is lexicographically less than the second */
204*db6fe4d6SKees Cook STRCMP_TEST_EXPECT_LOWER(test, strcmp, "Hello, KUnit!", "Hello, Kernel!");
205*db6fe4d6SKees Cook /* First string is lexicographically larger than the second */
206*db6fe4d6SKees Cook STRCMP_TEST_EXPECT_GREATER(test, strcmp, "Hello, Kernel!", "Hello, KUnit!");
207*db6fe4d6SKees Cook /* Empty string is always lexicographically less than any non-empty string */
208*db6fe4d6SKees Cook STRCMP_TEST_EXPECT_LOWER(test, strcmp, "", "Non-empty string");
209*db6fe4d6SKees Cook /* Two empty strings should be equal */
210*db6fe4d6SKees Cook STRCMP_TEST_EXPECT_EQUAL(test, strcmp, "", "");
211*db6fe4d6SKees Cook /* Compare two strings which have only one char difference */
212*db6fe4d6SKees Cook STRCMP_TEST_EXPECT_LOWER(test, strcmp, "Abacaba", "Abadaba");
213*db6fe4d6SKees Cook /* Compare two strings which have the same prefix*/
214*db6fe4d6SKees Cook STRCMP_TEST_EXPECT_LOWER(test, strcmp, "Just a string", "Just a string and something else");
215*db6fe4d6SKees Cook }
216*db6fe4d6SKees Cook
string_test_strcmp_long_strings(struct kunit * test)217*db6fe4d6SKees Cook static void string_test_strcmp_long_strings(struct kunit *test)
218*db6fe4d6SKees Cook {
219*db6fe4d6SKees Cook strcmp_fill_buffers('B', 'B');
220*db6fe4d6SKees Cook STRCMP_TEST_EXPECT_EQUAL(test, strcmp, strcmp_buffer1, strcmp_buffer2);
221*db6fe4d6SKees Cook
222*db6fe4d6SKees Cook strcmp_buffer1[STRCMP_CHANGE_POINT] = 'A';
223*db6fe4d6SKees Cook STRCMP_TEST_EXPECT_LOWER(test, strcmp, strcmp_buffer1, strcmp_buffer2);
224*db6fe4d6SKees Cook
225*db6fe4d6SKees Cook strcmp_buffer1[STRCMP_CHANGE_POINT] = 'C';
226*db6fe4d6SKees Cook STRCMP_TEST_EXPECT_GREATER(test, strcmp, strcmp_buffer1, strcmp_buffer2);
227*db6fe4d6SKees Cook }
228*db6fe4d6SKees Cook
string_test_strncmp(struct kunit * test)229*db6fe4d6SKees Cook static void string_test_strncmp(struct kunit *test)
230*db6fe4d6SKees Cook {
231*db6fe4d6SKees Cook /* Equal strings */
232*db6fe4d6SKees Cook STRCMP_TEST_EXPECT_EQUAL(test, strncmp, "Hello, KUnit!", "Hello, KUnit!", 13);
233*db6fe4d6SKees Cook /* First string is lexicographically less than the second */
234*db6fe4d6SKees Cook STRCMP_TEST_EXPECT_LOWER(test, strncmp, "Hello, KUnit!", "Hello, Kernel!", 13);
235*db6fe4d6SKees Cook /* Result is always 'equal' when count = 0 */
236*db6fe4d6SKees Cook STRCMP_TEST_EXPECT_EQUAL(test, strncmp, "Hello, Kernel!", "Hello, KUnit!", 0);
237*db6fe4d6SKees Cook /* Strings with common prefix are equal if count = length of prefix */
238*db6fe4d6SKees Cook STRCMP_TEST_EXPECT_EQUAL(test, strncmp, "Abacaba", "Abadaba", 3);
239*db6fe4d6SKees Cook /* Strings with common prefix are not equal when count = length of prefix + 1 */
240*db6fe4d6SKees Cook STRCMP_TEST_EXPECT_LOWER(test, strncmp, "Abacaba", "Abadaba", 4);
241*db6fe4d6SKees Cook /* If one string is a prefix of another, the shorter string is lexicographically smaller */
242*db6fe4d6SKees Cook STRCMP_TEST_EXPECT_LOWER(test, strncmp, "Just a string", "Just a string and something else",
243*db6fe4d6SKees Cook strlen("Just a string and something else"));
244*db6fe4d6SKees Cook /*
245*db6fe4d6SKees Cook * If one string is a prefix of another, and we check first length
246*db6fe4d6SKees Cook * of prefix chars, the result is 'equal'
247*db6fe4d6SKees Cook */
248*db6fe4d6SKees Cook STRCMP_TEST_EXPECT_EQUAL(test, strncmp, "Just a string", "Just a string and something else",
249*db6fe4d6SKees Cook strlen("Just a string"));
250*db6fe4d6SKees Cook }
251*db6fe4d6SKees Cook
string_test_strncmp_long_strings(struct kunit * test)252*db6fe4d6SKees Cook static void string_test_strncmp_long_strings(struct kunit *test)
253*db6fe4d6SKees Cook {
254*db6fe4d6SKees Cook strcmp_fill_buffers('B', 'B');
255*db6fe4d6SKees Cook STRCMP_TEST_EXPECT_EQUAL(test, strncmp, strcmp_buffer1,
256*db6fe4d6SKees Cook strcmp_buffer2, STRCMP_LARGE_BUF_LEN);
257*db6fe4d6SKees Cook
258*db6fe4d6SKees Cook strcmp_buffer1[STRCMP_CHANGE_POINT] = 'A';
259*db6fe4d6SKees Cook STRCMP_TEST_EXPECT_LOWER(test, strncmp, strcmp_buffer1,
260*db6fe4d6SKees Cook strcmp_buffer2, STRCMP_LARGE_BUF_LEN);
261*db6fe4d6SKees Cook
262*db6fe4d6SKees Cook strcmp_buffer1[STRCMP_CHANGE_POINT] = 'C';
263*db6fe4d6SKees Cook STRCMP_TEST_EXPECT_GREATER(test, strncmp, strcmp_buffer1,
264*db6fe4d6SKees Cook strcmp_buffer2, STRCMP_LARGE_BUF_LEN);
265*db6fe4d6SKees Cook /* the strings are equal up to STRCMP_CHANGE_POINT */
266*db6fe4d6SKees Cook STRCMP_TEST_EXPECT_EQUAL(test, strncmp, strcmp_buffer1,
267*db6fe4d6SKees Cook strcmp_buffer2, STRCMP_CHANGE_POINT);
268*db6fe4d6SKees Cook STRCMP_TEST_EXPECT_GREATER(test, strncmp, strcmp_buffer1,
269*db6fe4d6SKees Cook strcmp_buffer2, STRCMP_CHANGE_POINT + 1);
270*db6fe4d6SKees Cook }
271*db6fe4d6SKees Cook
string_test_strcasecmp(struct kunit * test)272*db6fe4d6SKees Cook static void string_test_strcasecmp(struct kunit *test)
273*db6fe4d6SKees Cook {
274*db6fe4d6SKees Cook /* Same strings in different case should be equal */
275*db6fe4d6SKees Cook STRCMP_TEST_EXPECT_EQUAL(test, strcasecmp, "Hello, Kernel!", "HeLLO, KErNeL!");
276*db6fe4d6SKees Cook /* Empty strings should be equal */
277*db6fe4d6SKees Cook STRCMP_TEST_EXPECT_EQUAL(test, strcasecmp, "", "");
278*db6fe4d6SKees Cook /* Despite ascii code for 'a' is larger than ascii code for 'B', 'a' < 'B' */
279*db6fe4d6SKees Cook STRCMP_TEST_EXPECT_LOWER(test, strcasecmp, "a", "B");
280*db6fe4d6SKees Cook STRCMP_TEST_EXPECT_GREATER(test, strcasecmp, "B", "a");
281*db6fe4d6SKees Cook /* Special symbols and numbers should be processed correctly */
282*db6fe4d6SKees Cook STRCMP_TEST_EXPECT_EQUAL(test, strcasecmp, "-+**.1230ghTTT~^", "-+**.1230Ghttt~^");
283*db6fe4d6SKees Cook }
284*db6fe4d6SKees Cook
string_test_strcasecmp_long_strings(struct kunit * test)285*db6fe4d6SKees Cook static void string_test_strcasecmp_long_strings(struct kunit *test)
286*db6fe4d6SKees Cook {
287*db6fe4d6SKees Cook strcmp_fill_buffers('b', 'B');
288*db6fe4d6SKees Cook STRCMP_TEST_EXPECT_EQUAL(test, strcasecmp, strcmp_buffer1, strcmp_buffer2);
289*db6fe4d6SKees Cook
290*db6fe4d6SKees Cook strcmp_buffer1[STRCMP_CHANGE_POINT] = 'a';
291*db6fe4d6SKees Cook STRCMP_TEST_EXPECT_LOWER(test, strcasecmp, strcmp_buffer1, strcmp_buffer2);
292*db6fe4d6SKees Cook
293*db6fe4d6SKees Cook strcmp_buffer1[STRCMP_CHANGE_POINT] = 'C';
294*db6fe4d6SKees Cook STRCMP_TEST_EXPECT_GREATER(test, strcasecmp, strcmp_buffer1, strcmp_buffer2);
295*db6fe4d6SKees Cook }
296*db6fe4d6SKees Cook
string_test_strncasecmp(struct kunit * test)297*db6fe4d6SKees Cook static void string_test_strncasecmp(struct kunit *test)
298*db6fe4d6SKees Cook {
299*db6fe4d6SKees Cook /* Same strings in different case should be equal */
300*db6fe4d6SKees Cook STRCMP_TEST_EXPECT_EQUAL(test, strncasecmp, "AbAcAbA", "Abacaba", strlen("Abacaba"));
301*db6fe4d6SKees Cook /* strncasecmp should check 'count' chars only */
302*db6fe4d6SKees Cook STRCMP_TEST_EXPECT_EQUAL(test, strncasecmp, "AbaCaBa", "abaCaDa", 5);
303*db6fe4d6SKees Cook STRCMP_TEST_EXPECT_LOWER(test, strncasecmp, "a", "B", 1);
304*db6fe4d6SKees Cook STRCMP_TEST_EXPECT_GREATER(test, strncasecmp, "B", "a", 1);
305*db6fe4d6SKees Cook /* Result is always 'equal' when count = 0 */
306*db6fe4d6SKees Cook STRCMP_TEST_EXPECT_EQUAL(test, strncasecmp, "Abacaba", "Not abacaba", 0);
307*db6fe4d6SKees Cook }
308*db6fe4d6SKees Cook
string_test_strncasecmp_long_strings(struct kunit * test)309*db6fe4d6SKees Cook static void string_test_strncasecmp_long_strings(struct kunit *test)
310*db6fe4d6SKees Cook {
311*db6fe4d6SKees Cook strcmp_fill_buffers('b', 'B');
312*db6fe4d6SKees Cook STRCMP_TEST_EXPECT_EQUAL(test, strncasecmp, strcmp_buffer1,
313*db6fe4d6SKees Cook strcmp_buffer2, STRCMP_LARGE_BUF_LEN);
314*db6fe4d6SKees Cook
315*db6fe4d6SKees Cook strcmp_buffer1[STRCMP_CHANGE_POINT] = 'a';
316*db6fe4d6SKees Cook STRCMP_TEST_EXPECT_LOWER(test, strncasecmp, strcmp_buffer1,
317*db6fe4d6SKees Cook strcmp_buffer2, STRCMP_LARGE_BUF_LEN);
318*db6fe4d6SKees Cook
319*db6fe4d6SKees Cook strcmp_buffer1[STRCMP_CHANGE_POINT] = 'C';
320*db6fe4d6SKees Cook STRCMP_TEST_EXPECT_GREATER(test, strncasecmp, strcmp_buffer1,
321*db6fe4d6SKees Cook strcmp_buffer2, STRCMP_LARGE_BUF_LEN);
322*db6fe4d6SKees Cook
323*db6fe4d6SKees Cook STRCMP_TEST_EXPECT_EQUAL(test, strncasecmp, strcmp_buffer1,
324*db6fe4d6SKees Cook strcmp_buffer2, STRCMP_CHANGE_POINT);
325*db6fe4d6SKees Cook STRCMP_TEST_EXPECT_GREATER(test, strncasecmp, strcmp_buffer1,
326*db6fe4d6SKees Cook strcmp_buffer2, STRCMP_CHANGE_POINT + 1);
327*db6fe4d6SKees Cook }
328*db6fe4d6SKees Cook
329*db6fe4d6SKees Cook /**
330*db6fe4d6SKees Cook * strscpy_check() - Run a specific test case.
331*db6fe4d6SKees Cook * @test: KUnit test context pointer
332*db6fe4d6SKees Cook * @src: Source string, argument to strscpy_pad()
333*db6fe4d6SKees Cook * @count: Size of destination buffer, argument to strscpy_pad()
334*db6fe4d6SKees Cook * @expected: Expected return value from call to strscpy_pad()
335*db6fe4d6SKees Cook * @chars: Number of characters from the src string expected to be
336*db6fe4d6SKees Cook * written to the dst buffer.
337*db6fe4d6SKees Cook * @terminator: 1 if there should be a terminating null byte 0 otherwise.
338*db6fe4d6SKees Cook * @pad: Number of pad characters expected (in the tail of dst buffer).
339*db6fe4d6SKees Cook * (@pad does not include the null terminator byte.)
340*db6fe4d6SKees Cook *
341*db6fe4d6SKees Cook * Calls strscpy_pad() and verifies the return value and state of the
342*db6fe4d6SKees Cook * destination buffer after the call returns.
343*db6fe4d6SKees Cook */
strscpy_check(struct kunit * test,char * src,int count,int expected,int chars,int terminator,int pad)344*db6fe4d6SKees Cook static void strscpy_check(struct kunit *test, char *src, int count,
345*db6fe4d6SKees Cook int expected, int chars, int terminator, int pad)
346*db6fe4d6SKees Cook {
347*db6fe4d6SKees Cook int nr_bytes_poison;
348*db6fe4d6SKees Cook int max_expected;
349*db6fe4d6SKees Cook int max_count;
350*db6fe4d6SKees Cook int written;
351*db6fe4d6SKees Cook char buf[6];
352*db6fe4d6SKees Cook int index, i;
353*db6fe4d6SKees Cook const char POISON = 'z';
354*db6fe4d6SKees Cook
355*db6fe4d6SKees Cook KUNIT_ASSERT_TRUE_MSG(test, src != NULL,
356*db6fe4d6SKees Cook "null source string not supported");
357*db6fe4d6SKees Cook
358*db6fe4d6SKees Cook memset(buf, POISON, sizeof(buf));
359*db6fe4d6SKees Cook /* Future proofing test suite, validate args */
360*db6fe4d6SKees Cook max_count = sizeof(buf) - 2; /* Space for null and to verify overflow */
361*db6fe4d6SKees Cook max_expected = count - 1; /* Space for the null */
362*db6fe4d6SKees Cook
363*db6fe4d6SKees Cook KUNIT_ASSERT_LE_MSG(test, count, max_count,
364*db6fe4d6SKees Cook "count (%d) is too big (%d) ... aborting", count, max_count);
365*db6fe4d6SKees Cook KUNIT_EXPECT_LE_MSG(test, expected, max_expected,
366*db6fe4d6SKees Cook "expected (%d) is bigger than can possibly be returned (%d)",
367*db6fe4d6SKees Cook expected, max_expected);
368*db6fe4d6SKees Cook
369*db6fe4d6SKees Cook written = strscpy_pad(buf, src, count);
370*db6fe4d6SKees Cook KUNIT_ASSERT_EQ(test, written, expected);
371*db6fe4d6SKees Cook
372*db6fe4d6SKees Cook if (count && written == -E2BIG) {
373*db6fe4d6SKees Cook KUNIT_ASSERT_EQ_MSG(test, 0, strncmp(buf, src, count - 1),
374*db6fe4d6SKees Cook "buffer state invalid for -E2BIG");
375*db6fe4d6SKees Cook KUNIT_ASSERT_EQ_MSG(test, buf[count - 1], '\0',
376*db6fe4d6SKees Cook "too big string is not null terminated correctly");
377*db6fe4d6SKees Cook }
378*db6fe4d6SKees Cook
379*db6fe4d6SKees Cook for (i = 0; i < chars; i++)
380*db6fe4d6SKees Cook KUNIT_ASSERT_EQ_MSG(test, buf[i], src[i],
381*db6fe4d6SKees Cook "buf[i]==%c != src[i]==%c", buf[i], src[i]);
382*db6fe4d6SKees Cook
383*db6fe4d6SKees Cook if (terminator)
384*db6fe4d6SKees Cook KUNIT_ASSERT_EQ_MSG(test, buf[count - 1], '\0',
385*db6fe4d6SKees Cook "string is not null terminated correctly");
386*db6fe4d6SKees Cook
387*db6fe4d6SKees Cook for (i = 0; i < pad; i++) {
388*db6fe4d6SKees Cook index = chars + terminator + i;
389*db6fe4d6SKees Cook KUNIT_ASSERT_EQ_MSG(test, buf[index], '\0',
390*db6fe4d6SKees Cook "padding missing at index: %d", i);
391*db6fe4d6SKees Cook }
392*db6fe4d6SKees Cook
393*db6fe4d6SKees Cook nr_bytes_poison = sizeof(buf) - chars - terminator - pad;
394*db6fe4d6SKees Cook for (i = 0; i < nr_bytes_poison; i++) {
395*db6fe4d6SKees Cook index = sizeof(buf) - 1 - i; /* Check from the end back */
396*db6fe4d6SKees Cook KUNIT_ASSERT_EQ_MSG(test, buf[index], POISON,
397*db6fe4d6SKees Cook "poison value missing at index: %d", i);
398*db6fe4d6SKees Cook }
399*db6fe4d6SKees Cook }
400*db6fe4d6SKees Cook
string_test_strscpy(struct kunit * test)401*db6fe4d6SKees Cook static void string_test_strscpy(struct kunit *test)
402*db6fe4d6SKees Cook {
403*db6fe4d6SKees Cook char dest[8];
404*db6fe4d6SKees Cook
405*db6fe4d6SKees Cook /*
406*db6fe4d6SKees Cook * strscpy_check() uses a destination buffer of size 6 and needs at
407*db6fe4d6SKees Cook * least 2 characters spare (one for null and one to check for
408*db6fe4d6SKees Cook * overflow). This means we should only call tc() with
409*db6fe4d6SKees Cook * strings up to a maximum of 4 characters long and 'count'
410*db6fe4d6SKees Cook * should not exceed 4. To test with longer strings increase
411*db6fe4d6SKees Cook * the buffer size in tc().
412*db6fe4d6SKees Cook */
413*db6fe4d6SKees Cook
414*db6fe4d6SKees Cook /* strscpy_check(test, src, count, expected, chars, terminator, pad) */
415*db6fe4d6SKees Cook strscpy_check(test, "a", 0, -E2BIG, 0, 0, 0);
416*db6fe4d6SKees Cook strscpy_check(test, "", 0, -E2BIG, 0, 0, 0);
417*db6fe4d6SKees Cook
418*db6fe4d6SKees Cook strscpy_check(test, "a", 1, -E2BIG, 0, 1, 0);
419*db6fe4d6SKees Cook strscpy_check(test, "", 1, 0, 0, 1, 0);
420*db6fe4d6SKees Cook
421*db6fe4d6SKees Cook strscpy_check(test, "ab", 2, -E2BIG, 1, 1, 0);
422*db6fe4d6SKees Cook strscpy_check(test, "a", 2, 1, 1, 1, 0);
423*db6fe4d6SKees Cook strscpy_check(test, "", 2, 0, 0, 1, 1);
424*db6fe4d6SKees Cook
425*db6fe4d6SKees Cook strscpy_check(test, "abc", 3, -E2BIG, 2, 1, 0);
426*db6fe4d6SKees Cook strscpy_check(test, "ab", 3, 2, 2, 1, 0);
427*db6fe4d6SKees Cook strscpy_check(test, "a", 3, 1, 1, 1, 1);
428*db6fe4d6SKees Cook strscpy_check(test, "", 3, 0, 0, 1, 2);
429*db6fe4d6SKees Cook
430*db6fe4d6SKees Cook strscpy_check(test, "abcd", 4, -E2BIG, 3, 1, 0);
431*db6fe4d6SKees Cook strscpy_check(test, "abc", 4, 3, 3, 1, 0);
432*db6fe4d6SKees Cook strscpy_check(test, "ab", 4, 2, 2, 1, 1);
433*db6fe4d6SKees Cook strscpy_check(test, "a", 4, 1, 1, 1, 2);
434*db6fe4d6SKees Cook strscpy_check(test, "", 4, 0, 0, 1, 3);
435*db6fe4d6SKees Cook
436*db6fe4d6SKees Cook /* Compile-time-known source strings. */
437*db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, strscpy(dest, "", ARRAY_SIZE(dest)), 0);
438*db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, strscpy(dest, "", 3), 0);
439*db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, strscpy(dest, "", 1), 0);
440*db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, strscpy(dest, "", 0), -E2BIG);
441*db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, strscpy(dest, "Fixed", ARRAY_SIZE(dest)), 5);
442*db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, strscpy(dest, "Fixed", 3), -E2BIG);
443*db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, strscpy(dest, "Fixed", 1), -E2BIG);
444*db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, strscpy(dest, "Fixed", 0), -E2BIG);
445*db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, strscpy(dest, "This is too long", ARRAY_SIZE(dest)), -E2BIG);
446*db6fe4d6SKees Cook }
447*db6fe4d6SKees Cook
448*db6fe4d6SKees Cook static volatile int unconst;
449*db6fe4d6SKees Cook
string_test_strcat(struct kunit * test)450*db6fe4d6SKees Cook static void string_test_strcat(struct kunit *test)
451*db6fe4d6SKees Cook {
452*db6fe4d6SKees Cook char dest[8];
453*db6fe4d6SKees Cook
454*db6fe4d6SKees Cook /* Destination is terminated. */
455*db6fe4d6SKees Cook memset(dest, 0, sizeof(dest));
456*db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, strlen(dest), 0);
457*db6fe4d6SKees Cook /* Empty copy does nothing. */
458*db6fe4d6SKees Cook KUNIT_EXPECT_TRUE(test, strcat(dest, "") == dest);
459*db6fe4d6SKees Cook KUNIT_EXPECT_STREQ(test, dest, "");
460*db6fe4d6SKees Cook /* 4 characters copied in, stops at %NUL. */
461*db6fe4d6SKees Cook KUNIT_EXPECT_TRUE(test, strcat(dest, "four\000123") == dest);
462*db6fe4d6SKees Cook KUNIT_EXPECT_STREQ(test, dest, "four");
463*db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, dest[5], '\0');
464*db6fe4d6SKees Cook /* 2 more characters copied in okay. */
465*db6fe4d6SKees Cook KUNIT_EXPECT_TRUE(test, strcat(dest, "AB") == dest);
466*db6fe4d6SKees Cook KUNIT_EXPECT_STREQ(test, dest, "fourAB");
467*db6fe4d6SKees Cook }
468*db6fe4d6SKees Cook
string_test_strncat(struct kunit * test)469*db6fe4d6SKees Cook static void string_test_strncat(struct kunit *test)
470*db6fe4d6SKees Cook {
471*db6fe4d6SKees Cook char dest[8];
472*db6fe4d6SKees Cook
473*db6fe4d6SKees Cook /* Destination is terminated. */
474*db6fe4d6SKees Cook memset(dest, 0, sizeof(dest));
475*db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, strlen(dest), 0);
476*db6fe4d6SKees Cook /* Empty copy of size 0 does nothing. */
477*db6fe4d6SKees Cook KUNIT_EXPECT_TRUE(test, strncat(dest, "", 0 + unconst) == dest);
478*db6fe4d6SKees Cook KUNIT_EXPECT_STREQ(test, dest, "");
479*db6fe4d6SKees Cook /* Empty copy of size 1 does nothing too. */
480*db6fe4d6SKees Cook KUNIT_EXPECT_TRUE(test, strncat(dest, "", 1 + unconst) == dest);
481*db6fe4d6SKees Cook KUNIT_EXPECT_STREQ(test, dest, "");
482*db6fe4d6SKees Cook /* Copy of max 0 characters should do nothing. */
483*db6fe4d6SKees Cook KUNIT_EXPECT_TRUE(test, strncat(dest, "asdf", 0 + unconst) == dest);
484*db6fe4d6SKees Cook KUNIT_EXPECT_STREQ(test, dest, "");
485*db6fe4d6SKees Cook
486*db6fe4d6SKees Cook /* 4 characters copied in, even if max is 8. */
487*db6fe4d6SKees Cook KUNIT_EXPECT_TRUE(test, strncat(dest, "four\000123", 8 + unconst) == dest);
488*db6fe4d6SKees Cook KUNIT_EXPECT_STREQ(test, dest, "four");
489*db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, dest[5], '\0');
490*db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, dest[6], '\0');
491*db6fe4d6SKees Cook /* 2 characters copied in okay, 2 ignored. */
492*db6fe4d6SKees Cook KUNIT_EXPECT_TRUE(test, strncat(dest, "ABCD", 2 + unconst) == dest);
493*db6fe4d6SKees Cook KUNIT_EXPECT_STREQ(test, dest, "fourAB");
494*db6fe4d6SKees Cook }
495*db6fe4d6SKees Cook
string_test_strlcat(struct kunit * test)496*db6fe4d6SKees Cook static void string_test_strlcat(struct kunit *test)
497*db6fe4d6SKees Cook {
498*db6fe4d6SKees Cook char dest[8] = "";
499*db6fe4d6SKees Cook int len = sizeof(dest) + unconst;
500*db6fe4d6SKees Cook
501*db6fe4d6SKees Cook /* Destination is terminated. */
502*db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, strlen(dest), 0);
503*db6fe4d6SKees Cook /* Empty copy is size 0. */
504*db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, strlcat(dest, "", len), 0);
505*db6fe4d6SKees Cook KUNIT_EXPECT_STREQ(test, dest, "");
506*db6fe4d6SKees Cook /* Size 1 should keep buffer terminated, report size of source only. */
507*db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, strlcat(dest, "four", 1 + unconst), 4);
508*db6fe4d6SKees Cook KUNIT_EXPECT_STREQ(test, dest, "");
509*db6fe4d6SKees Cook
510*db6fe4d6SKees Cook /* 4 characters copied in. */
511*db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, strlcat(dest, "four", len), 4);
512*db6fe4d6SKees Cook KUNIT_EXPECT_STREQ(test, dest, "four");
513*db6fe4d6SKees Cook /* 2 characters copied in okay, gets to 6 total. */
514*db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, strlcat(dest, "AB", len), 6);
515*db6fe4d6SKees Cook KUNIT_EXPECT_STREQ(test, dest, "fourAB");
516*db6fe4d6SKees Cook /* 2 characters ignored if max size (7) reached. */
517*db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, strlcat(dest, "CD", 7 + unconst), 8);
518*db6fe4d6SKees Cook KUNIT_EXPECT_STREQ(test, dest, "fourAB");
519*db6fe4d6SKees Cook /* 1 of 2 characters skipped, now at true max size. */
520*db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, strlcat(dest, "EFG", len), 9);
521*db6fe4d6SKees Cook KUNIT_EXPECT_STREQ(test, dest, "fourABE");
522*db6fe4d6SKees Cook /* Everything else ignored, now at full size. */
523*db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, strlcat(dest, "1234", len), 11);
524*db6fe4d6SKees Cook KUNIT_EXPECT_STREQ(test, dest, "fourABE");
525*db6fe4d6SKees Cook }
526*db6fe4d6SKees Cook
string_test_strtomem(struct kunit * test)527*db6fe4d6SKees Cook static void string_test_strtomem(struct kunit *test)
528*db6fe4d6SKees Cook {
529*db6fe4d6SKees Cook static const char input[sizeof(unsigned long)] = "hi";
530*db6fe4d6SKees Cook static const char truncate[] = "this is too long";
531*db6fe4d6SKees Cook struct {
532*db6fe4d6SKees Cook unsigned long canary1;
533*db6fe4d6SKees Cook unsigned char output[sizeof(unsigned long)] __nonstring;
534*db6fe4d6SKees Cook unsigned long canary2;
535*db6fe4d6SKees Cook } wrap;
536*db6fe4d6SKees Cook
537*db6fe4d6SKees Cook memset(&wrap, 0xFF, sizeof(wrap));
538*db6fe4d6SKees Cook KUNIT_EXPECT_EQ_MSG(test, wrap.canary1, ULONG_MAX,
539*db6fe4d6SKees Cook "bad initial canary value");
540*db6fe4d6SKees Cook KUNIT_EXPECT_EQ_MSG(test, wrap.canary2, ULONG_MAX,
541*db6fe4d6SKees Cook "bad initial canary value");
542*db6fe4d6SKees Cook
543*db6fe4d6SKees Cook /* Check unpadded copy leaves surroundings untouched. */
544*db6fe4d6SKees Cook strtomem(wrap.output, input);
545*db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, wrap.canary1, ULONG_MAX);
546*db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, wrap.output[0], input[0]);
547*db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, wrap.output[1], input[1]);
548*db6fe4d6SKees Cook for (size_t i = 2; i < sizeof(wrap.output); i++)
549*db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, wrap.output[i], 0xFF);
550*db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, wrap.canary2, ULONG_MAX);
551*db6fe4d6SKees Cook
552*db6fe4d6SKees Cook /* Check truncated copy leaves surroundings untouched. */
553*db6fe4d6SKees Cook memset(&wrap, 0xFF, sizeof(wrap));
554*db6fe4d6SKees Cook strtomem(wrap.output, truncate);
555*db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, wrap.canary1, ULONG_MAX);
556*db6fe4d6SKees Cook for (size_t i = 0; i < sizeof(wrap.output); i++)
557*db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, wrap.output[i], truncate[i]);
558*db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, wrap.canary2, ULONG_MAX);
559*db6fe4d6SKees Cook
560*db6fe4d6SKees Cook /* Check padded copy leaves only string padded. */
561*db6fe4d6SKees Cook memset(&wrap, 0xFF, sizeof(wrap));
562*db6fe4d6SKees Cook strtomem_pad(wrap.output, input, 0xAA);
563*db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, wrap.canary1, ULONG_MAX);
564*db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, wrap.output[0], input[0]);
565*db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, wrap.output[1], input[1]);
566*db6fe4d6SKees Cook for (size_t i = 2; i < sizeof(wrap.output); i++)
567*db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, wrap.output[i], 0xAA);
568*db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, wrap.canary2, ULONG_MAX);
569*db6fe4d6SKees Cook
570*db6fe4d6SKees Cook /* Check truncated padded copy has no padding. */
571*db6fe4d6SKees Cook memset(&wrap, 0xFF, sizeof(wrap));
572*db6fe4d6SKees Cook strtomem(wrap.output, truncate);
573*db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, wrap.canary1, ULONG_MAX);
574*db6fe4d6SKees Cook for (size_t i = 0; i < sizeof(wrap.output); i++)
575*db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, wrap.output[i], truncate[i]);
576*db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, wrap.canary2, ULONG_MAX);
577*db6fe4d6SKees Cook }
578*db6fe4d6SKees Cook
579*db6fe4d6SKees Cook
string_test_memtostr(struct kunit * test)580*db6fe4d6SKees Cook static void string_test_memtostr(struct kunit *test)
581*db6fe4d6SKees Cook {
582*db6fe4d6SKees Cook char nonstring[7] __nonstring = { 'a', 'b', 'c', 'd', 'e', 'f', 'g' };
583*db6fe4d6SKees Cook char nonstring_small[3] __nonstring = { 'a', 'b', 'c' };
584*db6fe4d6SKees Cook char dest[sizeof(nonstring) + 1];
585*db6fe4d6SKees Cook
586*db6fe4d6SKees Cook /* Copy in a non-NUL-terminated string into exactly right-sized dest. */
587*db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, sizeof(dest), sizeof(nonstring) + 1);
588*db6fe4d6SKees Cook memset(dest, 'X', sizeof(dest));
589*db6fe4d6SKees Cook memtostr(dest, nonstring);
590*db6fe4d6SKees Cook KUNIT_EXPECT_STREQ(test, dest, "abcdefg");
591*db6fe4d6SKees Cook memset(dest, 'X', sizeof(dest));
592*db6fe4d6SKees Cook memtostr(dest, nonstring_small);
593*db6fe4d6SKees Cook KUNIT_EXPECT_STREQ(test, dest, "abc");
594*db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, dest[7], 'X');
595*db6fe4d6SKees Cook
596*db6fe4d6SKees Cook memset(dest, 'X', sizeof(dest));
597*db6fe4d6SKees Cook memtostr_pad(dest, nonstring);
598*db6fe4d6SKees Cook KUNIT_EXPECT_STREQ(test, dest, "abcdefg");
599*db6fe4d6SKees Cook memset(dest, 'X', sizeof(dest));
600*db6fe4d6SKees Cook memtostr_pad(dest, nonstring_small);
601*db6fe4d6SKees Cook KUNIT_EXPECT_STREQ(test, dest, "abc");
602*db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, dest[7], '\0');
603*db6fe4d6SKees Cook }
604*db6fe4d6SKees Cook
605*db6fe4d6SKees Cook static struct kunit_case string_test_cases[] = {
606*db6fe4d6SKees Cook KUNIT_CASE(string_test_memset16),
607*db6fe4d6SKees Cook KUNIT_CASE(string_test_memset32),
608*db6fe4d6SKees Cook KUNIT_CASE(string_test_memset64),
609*db6fe4d6SKees Cook KUNIT_CASE(string_test_strchr),
610*db6fe4d6SKees Cook KUNIT_CASE(string_test_strnchr),
611*db6fe4d6SKees Cook KUNIT_CASE(string_test_strspn),
612*db6fe4d6SKees Cook KUNIT_CASE(string_test_strcmp),
613*db6fe4d6SKees Cook KUNIT_CASE(string_test_strcmp_long_strings),
614*db6fe4d6SKees Cook KUNIT_CASE(string_test_strncmp),
615*db6fe4d6SKees Cook KUNIT_CASE(string_test_strncmp_long_strings),
616*db6fe4d6SKees Cook KUNIT_CASE(string_test_strcasecmp),
617*db6fe4d6SKees Cook KUNIT_CASE(string_test_strcasecmp_long_strings),
618*db6fe4d6SKees Cook KUNIT_CASE(string_test_strncasecmp),
619*db6fe4d6SKees Cook KUNIT_CASE(string_test_strncasecmp_long_strings),
620*db6fe4d6SKees Cook KUNIT_CASE(string_test_strscpy),
621*db6fe4d6SKees Cook KUNIT_CASE(string_test_strcat),
622*db6fe4d6SKees Cook KUNIT_CASE(string_test_strncat),
623*db6fe4d6SKees Cook KUNIT_CASE(string_test_strlcat),
624*db6fe4d6SKees Cook KUNIT_CASE(string_test_strtomem),
625*db6fe4d6SKees Cook KUNIT_CASE(string_test_memtostr),
626*db6fe4d6SKees Cook {}
627*db6fe4d6SKees Cook };
628*db6fe4d6SKees Cook
629*db6fe4d6SKees Cook static struct kunit_suite string_test_suite = {
630*db6fe4d6SKees Cook .name = "string",
631*db6fe4d6SKees Cook .test_cases = string_test_cases,
632*db6fe4d6SKees Cook };
633*db6fe4d6SKees Cook
634*db6fe4d6SKees Cook kunit_test_suites(&string_test_suite);
635*db6fe4d6SKees Cook
636*db6fe4d6SKees Cook MODULE_DESCRIPTION("Test cases for string functions");
637*db6fe4d6SKees Cook MODULE_LICENSE("GPL v2");
638