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