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/module.h> 10 #include <linux/printk.h> 11 #include <linux/slab.h> 12 #include <linux/string.h> 13 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) 19 20 static void string_test_memset16(struct kunit *test) 21 { 22 unsigned i, j, k; 23 u16 v, *p; 24 25 p = kunit_kzalloc(test, 256 * 2 * 2, GFP_KERNEL); 26 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, p); 27 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++) { 33 v = p[k]; 34 if (k < i) { 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); 40 } else { 41 KUNIT_ASSERT_EQ_MSG(test, v, 0xa1a1, 42 "i:%d j:%d k:%d", i, j, k); 43 } 44 } 45 } 46 } 47 } 48 49 static void string_test_memset32(struct kunit *test) 50 { 51 unsigned i, j, k; 52 u32 v, *p; 53 54 p = kunit_kzalloc(test, 256 * 2 * 4, GFP_KERNEL); 55 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, p); 56 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++) { 62 v = p[k]; 63 if (k < i) { 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); 69 } else { 70 KUNIT_ASSERT_EQ_MSG(test, v, 0xa1a1a1a1, 71 "i:%d j:%d k:%d", i, j, k); 72 } 73 } 74 } 75 } 76 } 77 78 static void string_test_memset64(struct kunit *test) 79 { 80 unsigned i, j, k; 81 u64 v, *p; 82 83 p = kunit_kzalloc(test, 256 * 2 * 8, GFP_KERNEL); 84 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, p); 85 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++) { 91 v = p[k]; 92 if (k < i) { 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); 98 } else { 99 KUNIT_ASSERT_EQ_MSG(test, v, 0xa1a1a1a1a1a1a1a1ULL, 100 "i:%d j:%d k:%d", i, j, k); 101 } 102 } 103 } 104 } 105 } 106 107 static void string_test_strchr(struct kunit *test) 108 { 109 const char *test_string = "abcdefghijkl"; 110 const char *empty_string = ""; 111 char *result; 112 int i; 113 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, 117 "char:%c", 'a' + i); 118 } 119 120 result = strchr(empty_string, '\0'); 121 KUNIT_ASSERT_PTR_EQ(test, result, empty_string); 122 123 result = strchr(empty_string, 'a'); 124 KUNIT_ASSERT_NULL(test, result); 125 126 result = strchr(test_string, 'z'); 127 KUNIT_ASSERT_NULL(test, result); 128 } 129 130 static void string_test_strnchr(struct kunit *test) 131 { 132 const char *test_string = "abcdefghijkl"; 133 const char *empty_string = ""; 134 char *result; 135 int i, j; 136 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]); 140 if (j <= i) { 141 KUNIT_ASSERT_NULL_MSG(test, result, 142 "char:%c i:%d j:%d", 'a' + i, i, j); 143 } else { 144 KUNIT_ASSERT_EQ_MSG(test, result - test_string, i, 145 "char:%c i:%d j:%d", 'a' + i, i, j); 146 } 147 } 148 } 149 150 result = strnchr(empty_string, 0, '\0'); 151 KUNIT_ASSERT_NULL(test, result); 152 153 result = strnchr(empty_string, 1, '\0'); 154 KUNIT_ASSERT_PTR_EQ(test, result, empty_string); 155 156 result = strnchr(empty_string, 1, 'a'); 157 KUNIT_ASSERT_NULL(test, result); 158 159 result = strnchr(NULL, 0, '\0'); 160 KUNIT_ASSERT_NULL(test, result); 161 } 162 163 static void string_test_strspn(struct kunit *test) 164 { 165 static const struct strspn_test { 166 const char str[16]; 167 const char accept[16]; 168 const char reject[16]; 169 unsigned a; 170 unsigned r; 171 } tests[] = { 172 { "foobar", "", "", 0, 6 }, 173 { "abba", "abc", "ABBA", 4, 4 }, 174 { "abba", "a", "b", 1, 1 }, 175 { "", "abc", "abc", 0, 0}, 176 }; 177 const struct strspn_test *s = tests; 178 size_t i; 179 180 for (i = 0; i < ARRAY_SIZE(tests); ++i, ++s) { 181 KUNIT_ASSERT_EQ_MSG(test, s->a, strspn(s->str, s->accept), 182 "i:%zu", i); 183 KUNIT_ASSERT_EQ_MSG(test, s->r, strcspn(s->str, s->reject), 184 "i:%zu", i); 185 } 186 } 187 188 static char strcmp_buffer1[STRCMP_LARGE_BUF_LEN]; 189 static char strcmp_buffer2[STRCMP_LARGE_BUF_LEN]; 190 191 static void strcmp_fill_buffers(char fill1, char fill2) 192 { 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; 197 } 198 199 static void string_test_strcmp(struct kunit *test) 200 { 201 /* Equal strings */ 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"); 215 } 216 217 static void string_test_strcmp_long_strings(struct kunit *test) 218 { 219 strcmp_fill_buffers('B', 'B'); 220 STRCMP_TEST_EXPECT_EQUAL(test, strcmp, strcmp_buffer1, strcmp_buffer2); 221 222 strcmp_buffer1[STRCMP_CHANGE_POINT] = 'A'; 223 STRCMP_TEST_EXPECT_LOWER(test, strcmp, strcmp_buffer1, strcmp_buffer2); 224 225 strcmp_buffer1[STRCMP_CHANGE_POINT] = 'C'; 226 STRCMP_TEST_EXPECT_GREATER(test, strcmp, strcmp_buffer1, strcmp_buffer2); 227 } 228 229 static void string_test_strncmp(struct kunit *test) 230 { 231 /* Equal strings */ 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")); 244 /* 245 * If one string is a prefix of another, and we check first length 246 * of prefix chars, the result is 'equal' 247 */ 248 STRCMP_TEST_EXPECT_EQUAL(test, strncmp, "Just a string", "Just a string and something else", 249 strlen("Just a string")); 250 } 251 252 static void string_test_strncmp_long_strings(struct kunit *test) 253 { 254 strcmp_fill_buffers('B', 'B'); 255 STRCMP_TEST_EXPECT_EQUAL(test, strncmp, strcmp_buffer1, 256 strcmp_buffer2, STRCMP_LARGE_BUF_LEN); 257 258 strcmp_buffer1[STRCMP_CHANGE_POINT] = 'A'; 259 STRCMP_TEST_EXPECT_LOWER(test, strncmp, strcmp_buffer1, 260 strcmp_buffer2, STRCMP_LARGE_BUF_LEN); 261 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); 270 } 271 272 static void string_test_strcasecmp(struct kunit *test) 273 { 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~^"); 283 } 284 285 static void string_test_strcasecmp_long_strings(struct kunit *test) 286 { 287 strcmp_fill_buffers('b', 'B'); 288 STRCMP_TEST_EXPECT_EQUAL(test, strcasecmp, strcmp_buffer1, strcmp_buffer2); 289 290 strcmp_buffer1[STRCMP_CHANGE_POINT] = 'a'; 291 STRCMP_TEST_EXPECT_LOWER(test, strcasecmp, strcmp_buffer1, strcmp_buffer2); 292 293 strcmp_buffer1[STRCMP_CHANGE_POINT] = 'C'; 294 STRCMP_TEST_EXPECT_GREATER(test, strcasecmp, strcmp_buffer1, strcmp_buffer2); 295 } 296 297 static void string_test_strncasecmp(struct kunit *test) 298 { 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); 307 } 308 309 static void string_test_strncasecmp_long_strings(struct kunit *test) 310 { 311 strcmp_fill_buffers('b', 'B'); 312 STRCMP_TEST_EXPECT_EQUAL(test, strncasecmp, strcmp_buffer1, 313 strcmp_buffer2, STRCMP_LARGE_BUF_LEN); 314 315 strcmp_buffer1[STRCMP_CHANGE_POINT] = 'a'; 316 STRCMP_TEST_EXPECT_LOWER(test, strncasecmp, strcmp_buffer1, 317 strcmp_buffer2, STRCMP_LARGE_BUF_LEN); 318 319 strcmp_buffer1[STRCMP_CHANGE_POINT] = 'C'; 320 STRCMP_TEST_EXPECT_GREATER(test, strncasecmp, strcmp_buffer1, 321 strcmp_buffer2, STRCMP_LARGE_BUF_LEN); 322 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); 327 } 328 329 /** 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.) 340 * 341 * Calls strscpy_pad() and verifies the return value and state of the 342 * destination buffer after the call returns. 343 */ 344 static void strscpy_check(struct kunit *test, char *src, int count, 345 int expected, int chars, int terminator, int pad) 346 { 347 int nr_bytes_poison; 348 int max_expected; 349 int max_count; 350 int written; 351 char buf[6]; 352 int index, i; 353 const char POISON = 'z'; 354 355 KUNIT_ASSERT_TRUE_MSG(test, src != NULL, 356 "null source string not supported"); 357 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 */ 362 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); 368 369 written = strscpy_pad(buf, src, count); 370 KUNIT_ASSERT_EQ(test, written, expected); 371 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"); 377 } 378 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]); 382 383 if (terminator) 384 KUNIT_ASSERT_EQ_MSG(test, buf[count - 1], '\0', 385 "string is not null terminated correctly"); 386 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); 391 } 392 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); 398 } 399 } 400 401 static void string_test_strscpy(struct kunit *test) 402 { 403 char dest[8]; 404 405 /* 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(). 412 */ 413 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); 417 418 strscpy_check(test, "a", 1, -E2BIG, 0, 1, 0); 419 strscpy_check(test, "", 1, 0, 0, 1, 0); 420 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); 424 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); 429 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); 435 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); 446 } 447 448 static volatile int unconst; 449 450 static void string_test_strcat(struct kunit *test) 451 { 452 char dest[8]; 453 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"); 467 } 468 469 static void string_test_strncat(struct kunit *test) 470 { 471 char dest[8]; 472 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, ""); 485 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"); 494 } 495 496 static void string_test_strlcat(struct kunit *test) 497 { 498 char dest[8] = ""; 499 int len = sizeof(dest) + unconst; 500 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, ""); 509 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"); 525 } 526 527 static void string_test_strtomem(struct kunit *test) 528 { 529 static const char input[sizeof(unsigned long)] = "hi"; 530 static const char truncate[] = "this is too long"; 531 struct { 532 unsigned long canary1; 533 unsigned char output[sizeof(unsigned long)] __nonstring; 534 unsigned long canary2; 535 } wrap; 536 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"); 542 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); 551 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); 559 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); 569 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); 577 } 578 579 580 static void string_test_memtostr(struct kunit *test) 581 { 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]; 585 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'); 595 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'); 603 } 604 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), 626 {} 627 }; 628 629 static struct kunit_suite string_test_suite = { 630 .name = "string", 631 .test_cases = string_test_cases, 632 }; 633 634 kunit_test_suites(&string_test_suite); 635 636 MODULE_DESCRIPTION("Test cases for string functions"); 637 MODULE_LICENSE("GPL v2"); 638