1 // SPDX-License-Identifier: GPL-2.0-only
3 * Test cases for string functions.
6 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
8 #include <kunit/test.h>
9 #include <linux/module.h>
10 #include <linux/printk.h>
11 #include <linux/slab.h>
12 #include <linux/string.h>
14 #define STRCMP_LARGE_BUF_LEN 2048
15 #define STRCMP_CHANGE_POINT 1337
16 #define STRCMP_TEST_EXPECT_EQUAL(test, fn, ...) KUNIT_EXPECT_EQ(test, fn(__VA_ARGS__), 0)
17 #define STRCMP_TEST_EXPECT_LOWER(test, fn, ...) KUNIT_EXPECT_LT(test, fn(__VA_ARGS__), 0)
18 #define STRCMP_TEST_EXPECT_GREATER(test, fn, ...) KUNIT_EXPECT_GT(test, fn(__VA_ARGS__), 0)
20 static void string_test_memset16(struct kunit
*test
)
25 p
= kunit_kzalloc(test
, 256 * 2 * 2, GFP_KERNEL
);
26 KUNIT_ASSERT_NOT_ERR_OR_NULL(test
, p
);
28 for (i
= 0; i
< 256; i
++) {
29 for (j
= 0; j
< 256; j
++) {
30 memset(p
, 0xa1, 256 * 2 * sizeof(v
));
31 memset16(p
+ i
, 0xb1b2, j
);
32 for (k
= 0; k
< 512; k
++) {
35 KUNIT_ASSERT_EQ_MSG(test
, v
, 0xa1a1,
36 "i:%d j:%d k:%d", i
, j
, k
);
37 } else if (k
< i
+ j
) {
38 KUNIT_ASSERT_EQ_MSG(test
, v
, 0xb1b2,
39 "i:%d j:%d k:%d", i
, j
, k
);
41 KUNIT_ASSERT_EQ_MSG(test
, v
, 0xa1a1,
42 "i:%d j:%d k:%d", i
, j
, k
);
49 static void string_test_memset32(struct kunit
*test
)
54 p
= kunit_kzalloc(test
, 256 * 2 * 4, GFP_KERNEL
);
55 KUNIT_ASSERT_NOT_ERR_OR_NULL(test
, p
);
57 for (i
= 0; i
< 256; i
++) {
58 for (j
= 0; j
< 256; j
++) {
59 memset(p
, 0xa1, 256 * 2 * sizeof(v
));
60 memset32(p
+ i
, 0xb1b2b3b4, j
);
61 for (k
= 0; k
< 512; k
++) {
64 KUNIT_ASSERT_EQ_MSG(test
, v
, 0xa1a1a1a1,
65 "i:%d j:%d k:%d", i
, j
, k
);
66 } else if (k
< i
+ j
) {
67 KUNIT_ASSERT_EQ_MSG(test
, v
, 0xb1b2b3b4,
68 "i:%d j:%d k:%d", i
, j
, k
);
70 KUNIT_ASSERT_EQ_MSG(test
, v
, 0xa1a1a1a1,
71 "i:%d j:%d k:%d", i
, j
, k
);
78 static void string_test_memset64(struct kunit
*test
)
83 p
= kunit_kzalloc(test
, 256 * 2 * 8, GFP_KERNEL
);
84 KUNIT_ASSERT_NOT_ERR_OR_NULL(test
, p
);
86 for (i
= 0; i
< 256; i
++) {
87 for (j
= 0; j
< 256; j
++) {
88 memset(p
, 0xa1, 256 * 2 * sizeof(v
));
89 memset64(p
+ i
, 0xb1b2b3b4b5b6b7b8ULL
, j
);
90 for (k
= 0; k
< 512; k
++) {
93 KUNIT_ASSERT_EQ_MSG(test
, v
, 0xa1a1a1a1a1a1a1a1ULL
,
94 "i:%d j:%d k:%d", i
, j
, k
);
95 } else if (k
< i
+ j
) {
96 KUNIT_ASSERT_EQ_MSG(test
, v
, 0xb1b2b3b4b5b6b7b8ULL
,
97 "i:%d j:%d k:%d", i
, j
, k
);
99 KUNIT_ASSERT_EQ_MSG(test
, v
, 0xa1a1a1a1a1a1a1a1ULL
,
100 "i:%d j:%d k:%d", i
, j
, k
);
107 static void string_test_strchr(struct kunit
*test
)
109 const char *test_string
= "abcdefghijkl";
110 const char *empty_string
= "";
114 for (i
= 0; i
< strlen(test_string
) + 1; i
++) {
115 result
= strchr(test_string
, test_string
[i
]);
116 KUNIT_ASSERT_EQ_MSG(test
, result
- test_string
, i
,
120 result
= strchr(empty_string
, '\0');
121 KUNIT_ASSERT_PTR_EQ(test
, result
, empty_string
);
123 result
= strchr(empty_string
, 'a');
124 KUNIT_ASSERT_NULL(test
, result
);
126 result
= strchr(test_string
, 'z');
127 KUNIT_ASSERT_NULL(test
, result
);
130 static void string_test_strnchr(struct kunit
*test
)
132 const char *test_string
= "abcdefghijkl";
133 const char *empty_string
= "";
137 for (i
= 0; i
< strlen(test_string
) + 1; i
++) {
138 for (j
= 0; j
< strlen(test_string
) + 2; j
++) {
139 result
= strnchr(test_string
, j
, test_string
[i
]);
141 KUNIT_ASSERT_NULL_MSG(test
, result
,
142 "char:%c i:%d j:%d", 'a' + i
, i
, j
);
144 KUNIT_ASSERT_EQ_MSG(test
, result
- test_string
, i
,
145 "char:%c i:%d j:%d", 'a' + i
, i
, j
);
150 result
= strnchr(empty_string
, 0, '\0');
151 KUNIT_ASSERT_NULL(test
, result
);
153 result
= strnchr(empty_string
, 1, '\0');
154 KUNIT_ASSERT_PTR_EQ(test
, result
, empty_string
);
156 result
= strnchr(empty_string
, 1, 'a');
157 KUNIT_ASSERT_NULL(test
, result
);
159 result
= strnchr(NULL
, 0, '\0');
160 KUNIT_ASSERT_NULL(test
, result
);
163 static void string_test_strspn(struct kunit
*test
)
165 static const struct strspn_test
{
167 const char accept
[16];
168 const char reject
[16];
172 { "foobar", "", "", 0, 6 },
173 { "abba", "abc", "ABBA", 4, 4 },
174 { "abba", "a", "b", 1, 1 },
175 { "", "abc", "abc", 0, 0},
177 const struct strspn_test
*s
= tests
;
180 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
, ++s
) {
181 KUNIT_ASSERT_EQ_MSG(test
, s
->a
, strspn(s
->str
, s
->accept
),
183 KUNIT_ASSERT_EQ_MSG(test
, s
->r
, strcspn(s
->str
, s
->reject
),
188 static char strcmp_buffer1
[STRCMP_LARGE_BUF_LEN
];
189 static char strcmp_buffer2
[STRCMP_LARGE_BUF_LEN
];
191 static void strcmp_fill_buffers(char fill1
, char fill2
)
193 memset(strcmp_buffer1
, fill1
, STRCMP_LARGE_BUF_LEN
);
194 memset(strcmp_buffer2
, fill2
, STRCMP_LARGE_BUF_LEN
);
195 strcmp_buffer1
[STRCMP_LARGE_BUF_LEN
- 1] = 0;
196 strcmp_buffer2
[STRCMP_LARGE_BUF_LEN
- 1] = 0;
199 static void string_test_strcmp(struct kunit
*test
)
202 STRCMP_TEST_EXPECT_EQUAL(test
, strcmp
, "Hello, Kernel!", "Hello, Kernel!");
203 /* First string is lexicographically less than the second */
204 STRCMP_TEST_EXPECT_LOWER(test
, strcmp
, "Hello, KUnit!", "Hello, Kernel!");
205 /* First string is lexicographically larger than the second */
206 STRCMP_TEST_EXPECT_GREATER(test
, strcmp
, "Hello, Kernel!", "Hello, KUnit!");
207 /* Empty string is always lexicographically less than any non-empty string */
208 STRCMP_TEST_EXPECT_LOWER(test
, strcmp
, "", "Non-empty string");
209 /* Two empty strings should be equal */
210 STRCMP_TEST_EXPECT_EQUAL(test
, strcmp
, "", "");
211 /* Compare two strings which have only one char difference */
212 STRCMP_TEST_EXPECT_LOWER(test
, strcmp
, "Abacaba", "Abadaba");
213 /* Compare two strings which have the same prefix*/
214 STRCMP_TEST_EXPECT_LOWER(test
, strcmp
, "Just a string", "Just a string and something else");
217 static void string_test_strcmp_long_strings(struct kunit
*test
)
219 strcmp_fill_buffers('B', 'B');
220 STRCMP_TEST_EXPECT_EQUAL(test
, strcmp
, strcmp_buffer1
, strcmp_buffer2
);
222 strcmp_buffer1
[STRCMP_CHANGE_POINT
] = 'A';
223 STRCMP_TEST_EXPECT_LOWER(test
, strcmp
, strcmp_buffer1
, strcmp_buffer2
);
225 strcmp_buffer1
[STRCMP_CHANGE_POINT
] = 'C';
226 STRCMP_TEST_EXPECT_GREATER(test
, strcmp
, strcmp_buffer1
, strcmp_buffer2
);
229 static void string_test_strncmp(struct kunit
*test
)
232 STRCMP_TEST_EXPECT_EQUAL(test
, strncmp
, "Hello, KUnit!", "Hello, KUnit!", 13);
233 /* First string is lexicographically less than the second */
234 STRCMP_TEST_EXPECT_LOWER(test
, strncmp
, "Hello, KUnit!", "Hello, Kernel!", 13);
235 /* Result is always 'equal' when count = 0 */
236 STRCMP_TEST_EXPECT_EQUAL(test
, strncmp
, "Hello, Kernel!", "Hello, KUnit!", 0);
237 /* Strings with common prefix are equal if count = length of prefix */
238 STRCMP_TEST_EXPECT_EQUAL(test
, strncmp
, "Abacaba", "Abadaba", 3);
239 /* Strings with common prefix are not equal when count = length of prefix + 1 */
240 STRCMP_TEST_EXPECT_LOWER(test
, strncmp
, "Abacaba", "Abadaba", 4);
241 /* If one string is a prefix of another, the shorter string is lexicographically smaller */
242 STRCMP_TEST_EXPECT_LOWER(test
, strncmp
, "Just a string", "Just a string and something else",
243 strlen("Just a string and something else"));
245 * If one string is a prefix of another, and we check first length
246 * of prefix chars, the result is 'equal'
248 STRCMP_TEST_EXPECT_EQUAL(test
, strncmp
, "Just a string", "Just a string and something else",
249 strlen("Just a string"));
252 static void string_test_strncmp_long_strings(struct kunit
*test
)
254 strcmp_fill_buffers('B', 'B');
255 STRCMP_TEST_EXPECT_EQUAL(test
, strncmp
, strcmp_buffer1
,
256 strcmp_buffer2
, STRCMP_LARGE_BUF_LEN
);
258 strcmp_buffer1
[STRCMP_CHANGE_POINT
] = 'A';
259 STRCMP_TEST_EXPECT_LOWER(test
, strncmp
, strcmp_buffer1
,
260 strcmp_buffer2
, STRCMP_LARGE_BUF_LEN
);
262 strcmp_buffer1
[STRCMP_CHANGE_POINT
] = 'C';
263 STRCMP_TEST_EXPECT_GREATER(test
, strncmp
, strcmp_buffer1
,
264 strcmp_buffer2
, STRCMP_LARGE_BUF_LEN
);
265 /* the strings are equal up to STRCMP_CHANGE_POINT */
266 STRCMP_TEST_EXPECT_EQUAL(test
, strncmp
, strcmp_buffer1
,
267 strcmp_buffer2
, STRCMP_CHANGE_POINT
);
268 STRCMP_TEST_EXPECT_GREATER(test
, strncmp
, strcmp_buffer1
,
269 strcmp_buffer2
, STRCMP_CHANGE_POINT
+ 1);
272 static void string_test_strcasecmp(struct kunit
*test
)
274 /* Same strings in different case should be equal */
275 STRCMP_TEST_EXPECT_EQUAL(test
, strcasecmp
, "Hello, Kernel!", "HeLLO, KErNeL!");
276 /* Empty strings should be equal */
277 STRCMP_TEST_EXPECT_EQUAL(test
, strcasecmp
, "", "");
278 /* Despite ascii code for 'a' is larger than ascii code for 'B', 'a' < 'B' */
279 STRCMP_TEST_EXPECT_LOWER(test
, strcasecmp
, "a", "B");
280 STRCMP_TEST_EXPECT_GREATER(test
, strcasecmp
, "B", "a");
281 /* Special symbols and numbers should be processed correctly */
282 STRCMP_TEST_EXPECT_EQUAL(test
, strcasecmp
, "-+**.1230ghTTT~^", "-+**.1230Ghttt~^");
285 static void string_test_strcasecmp_long_strings(struct kunit
*test
)
287 strcmp_fill_buffers('b', 'B');
288 STRCMP_TEST_EXPECT_EQUAL(test
, strcasecmp
, strcmp_buffer1
, strcmp_buffer2
);
290 strcmp_buffer1
[STRCMP_CHANGE_POINT
] = 'a';
291 STRCMP_TEST_EXPECT_LOWER(test
, strcasecmp
, strcmp_buffer1
, strcmp_buffer2
);
293 strcmp_buffer1
[STRCMP_CHANGE_POINT
] = 'C';
294 STRCMP_TEST_EXPECT_GREATER(test
, strcasecmp
, strcmp_buffer1
, strcmp_buffer2
);
297 static void string_test_strncasecmp(struct kunit
*test
)
299 /* Same strings in different case should be equal */
300 STRCMP_TEST_EXPECT_EQUAL(test
, strncasecmp
, "AbAcAbA", "Abacaba", strlen("Abacaba"));
301 /* strncasecmp should check 'count' chars only */
302 STRCMP_TEST_EXPECT_EQUAL(test
, strncasecmp
, "AbaCaBa", "abaCaDa", 5);
303 STRCMP_TEST_EXPECT_LOWER(test
, strncasecmp
, "a", "B", 1);
304 STRCMP_TEST_EXPECT_GREATER(test
, strncasecmp
, "B", "a", 1);
305 /* Result is always 'equal' when count = 0 */
306 STRCMP_TEST_EXPECT_EQUAL(test
, strncasecmp
, "Abacaba", "Not abacaba", 0);
309 static void string_test_strncasecmp_long_strings(struct kunit
*test
)
311 strcmp_fill_buffers('b', 'B');
312 STRCMP_TEST_EXPECT_EQUAL(test
, strncasecmp
, strcmp_buffer1
,
313 strcmp_buffer2
, STRCMP_LARGE_BUF_LEN
);
315 strcmp_buffer1
[STRCMP_CHANGE_POINT
] = 'a';
316 STRCMP_TEST_EXPECT_LOWER(test
, strncasecmp
, strcmp_buffer1
,
317 strcmp_buffer2
, STRCMP_LARGE_BUF_LEN
);
319 strcmp_buffer1
[STRCMP_CHANGE_POINT
] = 'C';
320 STRCMP_TEST_EXPECT_GREATER(test
, strncasecmp
, strcmp_buffer1
,
321 strcmp_buffer2
, STRCMP_LARGE_BUF_LEN
);
323 STRCMP_TEST_EXPECT_EQUAL(test
, strncasecmp
, strcmp_buffer1
,
324 strcmp_buffer2
, STRCMP_CHANGE_POINT
);
325 STRCMP_TEST_EXPECT_GREATER(test
, strncasecmp
, strcmp_buffer1
,
326 strcmp_buffer2
, STRCMP_CHANGE_POINT
+ 1);
330 * strscpy_check() - Run a specific test case.
331 * @test: KUnit test context pointer
332 * @src: Source string, argument to strscpy_pad()
333 * @count: Size of destination buffer, argument to strscpy_pad()
334 * @expected: Expected return value from call to strscpy_pad()
335 * @chars: Number of characters from the src string expected to be
336 * written to the dst buffer.
337 * @terminator: 1 if there should be a terminating null byte 0 otherwise.
338 * @pad: Number of pad characters expected (in the tail of dst buffer).
339 * (@pad does not include the null terminator byte.)
341 * Calls strscpy_pad() and verifies the return value and state of the
342 * destination buffer after the call returns.
344 static void strscpy_check(struct kunit
*test
, char *src
, int count
,
345 int expected
, int chars
, int terminator
, int pad
)
353 const char POISON
= 'z';
355 KUNIT_ASSERT_TRUE_MSG(test
, src
!= NULL
,
356 "null source string not supported");
358 memset(buf
, POISON
, sizeof(buf
));
359 /* Future proofing test suite, validate args */
360 max_count
= sizeof(buf
) - 2; /* Space for null and to verify overflow */
361 max_expected
= count
- 1; /* Space for the null */
363 KUNIT_ASSERT_LE_MSG(test
, count
, max_count
,
364 "count (%d) is too big (%d) ... aborting", count
, max_count
);
365 KUNIT_EXPECT_LE_MSG(test
, expected
, max_expected
,
366 "expected (%d) is bigger than can possibly be returned (%d)",
367 expected
, max_expected
);
369 written
= strscpy_pad(buf
, src
, count
);
370 KUNIT_ASSERT_EQ(test
, written
, expected
);
372 if (count
&& written
== -E2BIG
) {
373 KUNIT_ASSERT_EQ_MSG(test
, 0, strncmp(buf
, src
, count
- 1),
374 "buffer state invalid for -E2BIG");
375 KUNIT_ASSERT_EQ_MSG(test
, buf
[count
- 1], '\0',
376 "too big string is not null terminated correctly");
379 for (i
= 0; i
< chars
; i
++)
380 KUNIT_ASSERT_EQ_MSG(test
, buf
[i
], src
[i
],
381 "buf[i]==%c != src[i]==%c", buf
[i
], src
[i
]);
384 KUNIT_ASSERT_EQ_MSG(test
, buf
[count
- 1], '\0',
385 "string is not null terminated correctly");
387 for (i
= 0; i
< pad
; i
++) {
388 index
= chars
+ terminator
+ i
;
389 KUNIT_ASSERT_EQ_MSG(test
, buf
[index
], '\0',
390 "padding missing at index: %d", i
);
393 nr_bytes_poison
= sizeof(buf
) - chars
- terminator
- pad
;
394 for (i
= 0; i
< nr_bytes_poison
; i
++) {
395 index
= sizeof(buf
) - 1 - i
; /* Check from the end back */
396 KUNIT_ASSERT_EQ_MSG(test
, buf
[index
], POISON
,
397 "poison value missing at index: %d", i
);
401 static void string_test_strscpy(struct kunit
*test
)
406 * strscpy_check() uses a destination buffer of size 6 and needs at
407 * least 2 characters spare (one for null and one to check for
408 * overflow). This means we should only call tc() with
409 * strings up to a maximum of 4 characters long and 'count'
410 * should not exceed 4. To test with longer strings increase
411 * the buffer size in tc().
414 /* strscpy_check(test, src, count, expected, chars, terminator, pad) */
415 strscpy_check(test
, "a", 0, -E2BIG
, 0, 0, 0);
416 strscpy_check(test
, "", 0, -E2BIG
, 0, 0, 0);
418 strscpy_check(test
, "a", 1, -E2BIG
, 0, 1, 0);
419 strscpy_check(test
, "", 1, 0, 0, 1, 0);
421 strscpy_check(test
, "ab", 2, -E2BIG
, 1, 1, 0);
422 strscpy_check(test
, "a", 2, 1, 1, 1, 0);
423 strscpy_check(test
, "", 2, 0, 0, 1, 1);
425 strscpy_check(test
, "abc", 3, -E2BIG
, 2, 1, 0);
426 strscpy_check(test
, "ab", 3, 2, 2, 1, 0);
427 strscpy_check(test
, "a", 3, 1, 1, 1, 1);
428 strscpy_check(test
, "", 3, 0, 0, 1, 2);
430 strscpy_check(test
, "abcd", 4, -E2BIG
, 3, 1, 0);
431 strscpy_check(test
, "abc", 4, 3, 3, 1, 0);
432 strscpy_check(test
, "ab", 4, 2, 2, 1, 1);
433 strscpy_check(test
, "a", 4, 1, 1, 1, 2);
434 strscpy_check(test
, "", 4, 0, 0, 1, 3);
436 /* Compile-time-known source strings. */
437 KUNIT_EXPECT_EQ(test
, strscpy(dest
, "", ARRAY_SIZE(dest
)), 0);
438 KUNIT_EXPECT_EQ(test
, strscpy(dest
, "", 3), 0);
439 KUNIT_EXPECT_EQ(test
, strscpy(dest
, "", 1), 0);
440 KUNIT_EXPECT_EQ(test
, strscpy(dest
, "", 0), -E2BIG
);
441 KUNIT_EXPECT_EQ(test
, strscpy(dest
, "Fixed", ARRAY_SIZE(dest
)), 5);
442 KUNIT_EXPECT_EQ(test
, strscpy(dest
, "Fixed", 3), -E2BIG
);
443 KUNIT_EXPECT_EQ(test
, strscpy(dest
, "Fixed", 1), -E2BIG
);
444 KUNIT_EXPECT_EQ(test
, strscpy(dest
, "Fixed", 0), -E2BIG
);
445 KUNIT_EXPECT_EQ(test
, strscpy(dest
, "This is too long", ARRAY_SIZE(dest
)), -E2BIG
);
448 static volatile int unconst
;
450 static void string_test_strcat(struct kunit
*test
)
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");
469 static void string_test_strncat(struct kunit
*test
)
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
, "");
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");
496 static void string_test_strlcat(struct kunit
*test
)
499 int len
= sizeof(dest
) + unconst
;
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
, "");
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");
527 static void string_test_strtomem(struct kunit
*test
)
529 static const char input
[sizeof(unsigned long)] = "hi";
530 static const char truncate
[] = "this is too long";
532 unsigned long canary1
;
533 unsigned char output
[sizeof(unsigned long)] __nonstring
;
534 unsigned long canary2
;
537 memset(&wrap
, 0xFF, sizeof(wrap
));
538 KUNIT_EXPECT_EQ_MSG(test
, wrap
.canary1
, ULONG_MAX
,
539 "bad initial canary value");
540 KUNIT_EXPECT_EQ_MSG(test
, wrap
.canary2
, ULONG_MAX
,
541 "bad initial canary value");
543 /* Check unpadded copy leaves surroundings untouched. */
544 strtomem(wrap
.output
, input
);
545 KUNIT_EXPECT_EQ(test
, wrap
.canary1
, ULONG_MAX
);
546 KUNIT_EXPECT_EQ(test
, wrap
.output
[0], input
[0]);
547 KUNIT_EXPECT_EQ(test
, wrap
.output
[1], input
[1]);
548 for (size_t i
= 2; i
< sizeof(wrap
.output
); i
++)
549 KUNIT_EXPECT_EQ(test
, wrap
.output
[i
], 0xFF);
550 KUNIT_EXPECT_EQ(test
, wrap
.canary2
, ULONG_MAX
);
552 /* Check truncated copy leaves surroundings untouched. */
553 memset(&wrap
, 0xFF, sizeof(wrap
));
554 strtomem(wrap
.output
, truncate
);
555 KUNIT_EXPECT_EQ(test
, wrap
.canary1
, ULONG_MAX
);
556 for (size_t i
= 0; i
< sizeof(wrap
.output
); i
++)
557 KUNIT_EXPECT_EQ(test
, wrap
.output
[i
], truncate
[i
]);
558 KUNIT_EXPECT_EQ(test
, wrap
.canary2
, ULONG_MAX
);
560 /* Check padded copy leaves only string padded. */
561 memset(&wrap
, 0xFF, sizeof(wrap
));
562 strtomem_pad(wrap
.output
, input
, 0xAA);
563 KUNIT_EXPECT_EQ(test
, wrap
.canary1
, ULONG_MAX
);
564 KUNIT_EXPECT_EQ(test
, wrap
.output
[0], input
[0]);
565 KUNIT_EXPECT_EQ(test
, wrap
.output
[1], input
[1]);
566 for (size_t i
= 2; i
< sizeof(wrap
.output
); i
++)
567 KUNIT_EXPECT_EQ(test
, wrap
.output
[i
], 0xAA);
568 KUNIT_EXPECT_EQ(test
, wrap
.canary2
, ULONG_MAX
);
570 /* Check truncated padded copy has no padding. */
571 memset(&wrap
, 0xFF, sizeof(wrap
));
572 strtomem(wrap
.output
, truncate
);
573 KUNIT_EXPECT_EQ(test
, wrap
.canary1
, ULONG_MAX
);
574 for (size_t i
= 0; i
< sizeof(wrap
.output
); i
++)
575 KUNIT_EXPECT_EQ(test
, wrap
.output
[i
], truncate
[i
]);
576 KUNIT_EXPECT_EQ(test
, wrap
.canary2
, ULONG_MAX
);
580 static void string_test_memtostr(struct kunit
*test
)
582 char nonstring
[7] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g' };
583 char nonstring_small
[3] = { 'a', 'b', 'c' };
584 char dest
[sizeof(nonstring
) + 1];
586 /* Copy in a non-NUL-terminated string into exactly right-sized dest. */
587 KUNIT_EXPECT_EQ(test
, sizeof(dest
), sizeof(nonstring
) + 1);
588 memset(dest
, 'X', sizeof(dest
));
589 memtostr(dest
, nonstring
);
590 KUNIT_EXPECT_STREQ(test
, dest
, "abcdefg");
591 memset(dest
, 'X', sizeof(dest
));
592 memtostr(dest
, nonstring_small
);
593 KUNIT_EXPECT_STREQ(test
, dest
, "abc");
594 KUNIT_EXPECT_EQ(test
, dest
[7], 'X');
596 memset(dest
, 'X', sizeof(dest
));
597 memtostr_pad(dest
, nonstring
);
598 KUNIT_EXPECT_STREQ(test
, dest
, "abcdefg");
599 memset(dest
, 'X', sizeof(dest
));
600 memtostr_pad(dest
, nonstring_small
);
601 KUNIT_EXPECT_STREQ(test
, dest
, "abc");
602 KUNIT_EXPECT_EQ(test
, dest
[7], '\0');
605 static struct kunit_case string_test_cases
[] = {
606 KUNIT_CASE(string_test_memset16
),
607 KUNIT_CASE(string_test_memset32
),
608 KUNIT_CASE(string_test_memset64
),
609 KUNIT_CASE(string_test_strchr
),
610 KUNIT_CASE(string_test_strnchr
),
611 KUNIT_CASE(string_test_strspn
),
612 KUNIT_CASE(string_test_strcmp
),
613 KUNIT_CASE(string_test_strcmp_long_strings
),
614 KUNIT_CASE(string_test_strncmp
),
615 KUNIT_CASE(string_test_strncmp_long_strings
),
616 KUNIT_CASE(string_test_strcasecmp
),
617 KUNIT_CASE(string_test_strcasecmp_long_strings
),
618 KUNIT_CASE(string_test_strncasecmp
),
619 KUNIT_CASE(string_test_strncasecmp_long_strings
),
620 KUNIT_CASE(string_test_strscpy
),
621 KUNIT_CASE(string_test_strcat
),
622 KUNIT_CASE(string_test_strncat
),
623 KUNIT_CASE(string_test_strlcat
),
624 KUNIT_CASE(string_test_strtomem
),
625 KUNIT_CASE(string_test_memtostr
),
629 static struct kunit_suite string_test_suite
= {
631 .test_cases
= string_test_cases
,
634 kunit_test_suites(&string_test_suite
);
636 MODULE_DESCRIPTION("Test cases for string functions");
637 MODULE_LICENSE("GPL v2");