1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Test cases for sscanf facility. 4 */ 5 6 #include <kunit/test.h> 7 #include <linux/bitops.h> 8 #include <linux/kernel.h> 9 #include <linux/module.h> 10 #include <linux/overflow.h> 11 #include <linux/prandom.h> 12 #include <linux/slab.h> 13 #include <linux/string.h> 14 15 #define BUF_SIZE 1024 16 17 static char *test_buffer; 18 static char *fmt_buffer; 19 static struct rnd_state rnd_state; 20 21 typedef void (*check_fn)(struct kunit *test, const char *file, const int line, 22 const void *check_data, const char *string, const char *fmt, int n_args, 23 va_list ap); 24 25 static void __scanf(7, 9) 26 _test(struct kunit *test, const char *file, const int line, check_fn fn, const void *check_data, 27 const char *string, const char *fmt, int n_args, ...) 28 { 29 va_list ap, ap_copy; 30 int ret; 31 32 va_start(ap, n_args); 33 va_copy(ap_copy, ap); 34 ret = vsscanf(string, fmt, ap_copy); 35 va_end(ap_copy); 36 37 if (ret != n_args) { 38 KUNIT_FAIL(test, "%s:%d: vsscanf(\"%s\", \"%s\", ...) returned %d expected %d", 39 file, line, string, fmt, ret, n_args); 40 } else { 41 (*fn)(test, file, line, check_data, string, fmt, n_args, ap); 42 } 43 44 va_end(ap); 45 } 46 47 #define _check_numbers_template(arg_fmt, expect, str, fmt, n_args, ap) \ 48 do { \ 49 for (; n_args > 0; n_args--, expect++) { \ 50 typeof(*expect) got = *va_arg(ap, typeof(expect)); \ 51 if (got != *expect) { \ 52 KUNIT_FAIL(test, \ 53 "%s:%d: vsscanf(\"%s\", \"%s\", ...) expected " arg_fmt " got " arg_fmt, \ 54 file, line, str, fmt, *expect, got); \ 55 return; \ 56 } \ 57 } \ 58 } while (0) 59 60 static void check_ull(struct kunit *test, const char *file, const int line, const void *check_data, 61 const char *string, const char *fmt, int n_args, va_list ap) 62 { 63 const unsigned long long *pval = check_data; 64 65 _check_numbers_template("%llu", pval, string, fmt, n_args, ap); 66 } 67 68 static void check_ll(struct kunit *test, const char *file, const int line, const void *check_data, 69 const char *string, const char *fmt, int n_args, va_list ap) 70 { 71 const long long *pval = check_data; 72 73 _check_numbers_template("%lld", pval, string, fmt, n_args, ap); 74 } 75 76 static void check_ulong(struct kunit *test, const char *file, const int line, 77 const void *check_data, const char *string, const char *fmt, int n_args, 78 va_list ap) 79 { 80 const unsigned long *pval = check_data; 81 82 _check_numbers_template("%lu", pval, string, fmt, n_args, ap); 83 } 84 85 static void check_long(struct kunit *test, const char *file, const int line, const void *check_data, 86 const char *string, const char *fmt, int n_args, va_list ap) 87 { 88 const long *pval = check_data; 89 90 _check_numbers_template("%ld", pval, string, fmt, n_args, ap); 91 } 92 93 static void check_uint(struct kunit *test, const char *file, const int line, const void *check_data, 94 const char *string, const char *fmt, int n_args, va_list ap) 95 { 96 const unsigned int *pval = check_data; 97 98 _check_numbers_template("%u", pval, string, fmt, n_args, ap); 99 } 100 101 static void check_int(struct kunit *test, const char *file, const int line, const void *check_data, 102 const char *string, const char *fmt, int n_args, va_list ap) 103 { 104 const int *pval = check_data; 105 106 _check_numbers_template("%d", pval, string, fmt, n_args, ap); 107 } 108 109 static void check_ushort(struct kunit *test, const char *file, const int line, 110 const void *check_data, const char *string, const char *fmt, int n_args, 111 va_list ap) 112 { 113 const unsigned short *pval = check_data; 114 115 _check_numbers_template("%hu", pval, string, fmt, n_args, ap); 116 } 117 118 static void check_short(struct kunit *test, const char *file, const int line, 119 const void *check_data, const char *string, const char *fmt, int n_args, 120 va_list ap) 121 { 122 const short *pval = check_data; 123 124 _check_numbers_template("%hd", pval, string, fmt, n_args, ap); 125 } 126 127 static void check_uchar(struct kunit *test, const char *file, const int line, 128 const void *check_data, const char *string, const char *fmt, int n_args, 129 va_list ap) 130 { 131 const unsigned char *pval = check_data; 132 133 _check_numbers_template("%hhu", pval, string, fmt, n_args, ap); 134 } 135 136 static void check_char(struct kunit *test, const char *file, const int line, const void *check_data, 137 const char *string, const char *fmt, int n_args, va_list ap) 138 { 139 const signed char *pval = check_data; 140 141 _check_numbers_template("%hhd", pval, string, fmt, n_args, ap); 142 } 143 144 /* Selection of interesting numbers to test, copied from test-kstrtox.c */ 145 static const unsigned long long numbers[] = { 146 0x0ULL, 147 0x1ULL, 148 0x7fULL, 149 0x80ULL, 150 0x81ULL, 151 0xffULL, 152 0x100ULL, 153 0x101ULL, 154 0x7fffULL, 155 0x8000ULL, 156 0x8001ULL, 157 0xffffULL, 158 0x10000ULL, 159 0x10001ULL, 160 0x7fffffffULL, 161 0x80000000ULL, 162 0x80000001ULL, 163 0xffffffffULL, 164 0x100000000ULL, 165 0x100000001ULL, 166 0x7fffffffffffffffULL, 167 0x8000000000000000ULL, 168 0x8000000000000001ULL, 169 0xfffffffffffffffeULL, 170 0xffffffffffffffffULL, 171 }; 172 173 #define value_representable_in_type(T, val) \ 174 (is_signed_type(T) \ 175 ? ((long long)(val) >= type_min(T)) && ((long long)(val) <= type_max(T)) \ 176 : ((unsigned long long)(val) <= type_max(T))) 177 178 179 #define test_one_number(T, gen_fmt, scan_fmt, val, fn) \ 180 do { \ 181 const T expect_val = (T)(val); \ 182 T result = ~expect_val; /* should be overwritten */ \ 183 \ 184 snprintf(test_buffer, BUF_SIZE, gen_fmt, expect_val); \ 185 _test(test, __FILE__, __LINE__, fn, &expect_val, test_buffer, "%" scan_fmt, 1, &result);\ 186 } while (0) 187 188 #define simple_numbers_loop(T, gen_fmt, scan_fmt, fn) \ 189 do { \ 190 int i; \ 191 \ 192 for (i = 0; i < ARRAY_SIZE(numbers); i++) { \ 193 if (value_representable_in_type(T, numbers[i])) \ 194 test_one_number(T, gen_fmt, scan_fmt, \ 195 numbers[i], fn); \ 196 \ 197 if (value_representable_in_type(T, -numbers[i])) \ 198 test_one_number(T, gen_fmt, scan_fmt, \ 199 -numbers[i], fn); \ 200 } \ 201 } while (0) 202 203 static void numbers_simple(struct kunit *test) 204 { 205 simple_numbers_loop(unsigned long long, "%llu", "llu", check_ull); 206 simple_numbers_loop(long long, "%lld", "lld", check_ll); 207 simple_numbers_loop(long long, "%lld", "lli", check_ll); 208 simple_numbers_loop(unsigned long long, "%llx", "llx", check_ull); 209 simple_numbers_loop(long long, "%llx", "llx", check_ll); 210 simple_numbers_loop(long long, "0x%llx", "lli", check_ll); 211 simple_numbers_loop(unsigned long long, "0x%llx", "llx", check_ull); 212 simple_numbers_loop(long long, "0x%llx", "llx", check_ll); 213 214 simple_numbers_loop(unsigned long, "%lu", "lu", check_ulong); 215 simple_numbers_loop(long, "%ld", "ld", check_long); 216 simple_numbers_loop(long, "%ld", "li", check_long); 217 simple_numbers_loop(unsigned long, "%lx", "lx", check_ulong); 218 simple_numbers_loop(long, "%lx", "lx", check_long); 219 simple_numbers_loop(long, "0x%lx", "li", check_long); 220 simple_numbers_loop(unsigned long, "0x%lx", "lx", check_ulong); 221 simple_numbers_loop(long, "0x%lx", "lx", check_long); 222 223 simple_numbers_loop(unsigned int, "%u", "u", check_uint); 224 simple_numbers_loop(int, "%d", "d", check_int); 225 simple_numbers_loop(int, "%d", "i", check_int); 226 simple_numbers_loop(unsigned int, "%x", "x", check_uint); 227 simple_numbers_loop(int, "%x", "x", check_int); 228 simple_numbers_loop(int, "0x%x", "i", check_int); 229 simple_numbers_loop(unsigned int, "0x%x", "x", check_uint); 230 simple_numbers_loop(int, "0x%x", "x", check_int); 231 232 simple_numbers_loop(unsigned short, "%hu", "hu", check_ushort); 233 simple_numbers_loop(short, "%hd", "hd", check_short); 234 simple_numbers_loop(short, "%hd", "hi", check_short); 235 simple_numbers_loop(unsigned short, "%hx", "hx", check_ushort); 236 simple_numbers_loop(short, "%hx", "hx", check_short); 237 simple_numbers_loop(short, "0x%hx", "hi", check_short); 238 simple_numbers_loop(unsigned short, "0x%hx", "hx", check_ushort); 239 simple_numbers_loop(short, "0x%hx", "hx", check_short); 240 241 simple_numbers_loop(unsigned char, "%hhu", "hhu", check_uchar); 242 simple_numbers_loop(signed char, "%hhd", "hhd", check_char); 243 simple_numbers_loop(signed char, "%hhd", "hhi", check_char); 244 simple_numbers_loop(unsigned char, "%hhx", "hhx", check_uchar); 245 simple_numbers_loop(signed char, "%hhx", "hhx", check_char); 246 simple_numbers_loop(signed char, "0x%hhx", "hhi", check_char); 247 simple_numbers_loop(unsigned char, "0x%hhx", "hhx", check_uchar); 248 simple_numbers_loop(signed char, "0x%hhx", "hhx", check_char); 249 } 250 251 /* 252 * This gives a better variety of number "lengths" in a small sample than 253 * the raw prandom*() functions (Not mathematically rigorous!!). 254 * Variabilty of length and value is more important than perfect randomness. 255 */ 256 static u32 next_test_random(u32 max_bits) 257 { 258 u32 n_bits = hweight32(prandom_u32_state(&rnd_state)) % (max_bits + 1); 259 260 return prandom_u32_state(&rnd_state) & GENMASK(n_bits, 0); 261 } 262 263 static unsigned long long next_test_random_ull(void) 264 { 265 u32 rand1 = prandom_u32_state(&rnd_state); 266 u32 n_bits = (hweight32(rand1) * 3) % 64; 267 u64 val = (u64)prandom_u32_state(&rnd_state) * rand1; 268 269 return val & GENMASK_ULL(n_bits, 0); 270 } 271 272 #define random_for_type(T) \ 273 ((T)(sizeof(T) <= sizeof(u32) \ 274 ? next_test_random(BITS_PER_TYPE(T)) \ 275 : next_test_random_ull())) 276 277 /* 278 * Define a pattern of negative and positive numbers to ensure we get 279 * some of both within the small number of samples in a test string. 280 */ 281 #define NEGATIVES_PATTERN 0x3246 /* 00110010 01000110 */ 282 283 #define fill_random_array(arr) \ 284 do { \ 285 unsigned int neg_pattern = NEGATIVES_PATTERN; \ 286 int i; \ 287 \ 288 for (i = 0; i < ARRAY_SIZE(arr); i++, neg_pattern >>= 1) { \ 289 (arr)[i] = random_for_type(typeof((arr)[0])); \ 290 if (is_signed_type(typeof((arr)[0])) && (neg_pattern & 1)) \ 291 (arr)[i] = -(arr)[i]; \ 292 } \ 293 } while (0) 294 295 /* 296 * Convenience wrapper around snprintf() to append at buf_pos in buf, 297 * updating buf_pos and returning the number of characters appended. 298 * On error buf_pos is not changed and return value is 0. 299 */ 300 static int __printf(4, 5) 301 append_fmt(char *buf, int *buf_pos, int buf_len, const char *val_fmt, ...) 302 { 303 va_list ap; 304 int field_len; 305 306 va_start(ap, val_fmt); 307 field_len = vsnprintf(buf + *buf_pos, buf_len - *buf_pos, val_fmt, ap); 308 va_end(ap); 309 310 if (field_len < 0) 311 field_len = 0; 312 313 *buf_pos += field_len; 314 315 return field_len; 316 } 317 318 /* 319 * Convenience function to append the field delimiter string 320 * to both the value string and format string buffers. 321 */ 322 static void append_delim(char *str_buf, int *str_buf_pos, int str_buf_len, 323 char *fmt_buf, int *fmt_buf_pos, int fmt_buf_len, 324 const char *delim_str) 325 { 326 append_fmt(str_buf, str_buf_pos, str_buf_len, delim_str); 327 append_fmt(fmt_buf, fmt_buf_pos, fmt_buf_len, delim_str); 328 } 329 330 #define test_array_8(fn, check_data, string, fmt, arr) \ 331 do { \ 332 BUILD_BUG_ON(ARRAY_SIZE(arr) != 8); \ 333 _test(test, __FILE__, __LINE__, fn, check_data, string, fmt, 8, \ 334 &(arr)[0], &(arr)[1], &(arr)[2], &(arr)[3], \ 335 &(arr)[4], &(arr)[5], &(arr)[6], &(arr)[7]); \ 336 } while (0) 337 338 #define numbers_list_8(T, gen_fmt, field_sep, scan_fmt, fn) \ 339 do { \ 340 int i, pos = 0, fmt_pos = 0; \ 341 T expect[8], result[8]; \ 342 \ 343 fill_random_array(expect); \ 344 \ 345 for (i = 0; i < ARRAY_SIZE(expect); i++) { \ 346 if (i != 0) \ 347 append_delim(test_buffer, &pos, BUF_SIZE, \ 348 fmt_buffer, &fmt_pos, BUF_SIZE, \ 349 field_sep); \ 350 \ 351 append_fmt(test_buffer, &pos, BUF_SIZE, gen_fmt, expect[i]); \ 352 append_fmt(fmt_buffer, &fmt_pos, BUF_SIZE, "%%%s", scan_fmt); \ 353 } \ 354 \ 355 test_array_8(fn, expect, test_buffer, fmt_buffer, result); \ 356 } while (0) 357 358 #define numbers_list_fix_width(T, gen_fmt, field_sep, width, scan_fmt, fn) \ 359 do { \ 360 char full_fmt[16]; \ 361 \ 362 snprintf(full_fmt, sizeof(full_fmt), "%u%s", width, scan_fmt); \ 363 numbers_list_8(T, gen_fmt, field_sep, full_fmt, fn); \ 364 } while (0) 365 366 #define numbers_list_val_width(T, gen_fmt, field_sep, scan_fmt, fn) \ 367 do { \ 368 int i, val_len, pos = 0, fmt_pos = 0; \ 369 T expect[8], result[8]; \ 370 \ 371 fill_random_array(expect); \ 372 \ 373 for (i = 0; i < ARRAY_SIZE(expect); i++) { \ 374 if (i != 0) \ 375 append_delim(test_buffer, &pos, BUF_SIZE, \ 376 fmt_buffer, &fmt_pos, BUF_SIZE, field_sep);\ 377 \ 378 val_len = append_fmt(test_buffer, &pos, BUF_SIZE, gen_fmt, \ 379 expect[i]); \ 380 append_fmt(fmt_buffer, &fmt_pos, BUF_SIZE, \ 381 "%%%u%s", val_len, scan_fmt); \ 382 } \ 383 \ 384 test_array_8(fn, expect, test_buffer, fmt_buffer, result); \ 385 } while (0) 386 387 static void numbers_list_ll(struct kunit *test, const char *delim) 388 { 389 numbers_list_8(unsigned long long, "%llu", delim, "llu", check_ull); 390 numbers_list_8(long long, "%lld", delim, "lld", check_ll); 391 numbers_list_8(long long, "%lld", delim, "lli", check_ll); 392 numbers_list_8(unsigned long long, "%llx", delim, "llx", check_ull); 393 numbers_list_8(unsigned long long, "0x%llx", delim, "llx", check_ull); 394 numbers_list_8(long long, "0x%llx", delim, "lli", check_ll); 395 } 396 397 static void numbers_list_l(struct kunit *test, const char *delim) 398 { 399 numbers_list_8(unsigned long, "%lu", delim, "lu", check_ulong); 400 numbers_list_8(long, "%ld", delim, "ld", check_long); 401 numbers_list_8(long, "%ld", delim, "li", check_long); 402 numbers_list_8(unsigned long, "%lx", delim, "lx", check_ulong); 403 numbers_list_8(unsigned long, "0x%lx", delim, "lx", check_ulong); 404 numbers_list_8(long, "0x%lx", delim, "li", check_long); 405 } 406 407 static void numbers_list_d(struct kunit *test, const char *delim) 408 { 409 numbers_list_8(unsigned int, "%u", delim, "u", check_uint); 410 numbers_list_8(int, "%d", delim, "d", check_int); 411 numbers_list_8(int, "%d", delim, "i", check_int); 412 numbers_list_8(unsigned int, "%x", delim, "x", check_uint); 413 numbers_list_8(unsigned int, "0x%x", delim, "x", check_uint); 414 numbers_list_8(int, "0x%x", delim, "i", check_int); 415 } 416 417 static void numbers_list_h(struct kunit *test, const char *delim) 418 { 419 numbers_list_8(unsigned short, "%hu", delim, "hu", check_ushort); 420 numbers_list_8(short, "%hd", delim, "hd", check_short); 421 numbers_list_8(short, "%hd", delim, "hi", check_short); 422 numbers_list_8(unsigned short, "%hx", delim, "hx", check_ushort); 423 numbers_list_8(unsigned short, "0x%hx", delim, "hx", check_ushort); 424 numbers_list_8(short, "0x%hx", delim, "hi", check_short); 425 } 426 427 static void numbers_list_hh(struct kunit *test, const char *delim) 428 { 429 numbers_list_8(unsigned char, "%hhu", delim, "hhu", check_uchar); 430 numbers_list_8(signed char, "%hhd", delim, "hhd", check_char); 431 numbers_list_8(signed char, "%hhd", delim, "hhi", check_char); 432 numbers_list_8(unsigned char, "%hhx", delim, "hhx", check_uchar); 433 numbers_list_8(unsigned char, "0x%hhx", delim, "hhx", check_uchar); 434 numbers_list_8(signed char, "0x%hhx", delim, "hhi", check_char); 435 } 436 437 static void numbers_list(struct kunit *test) 438 { 439 const char * const *param = test->param_value; 440 const char *delim = *param; 441 442 numbers_list_ll(test, delim); 443 numbers_list_l(test, delim); 444 numbers_list_d(test, delim); 445 numbers_list_h(test, delim); 446 numbers_list_hh(test, delim); 447 } 448 449 static void numbers_list_field_width_ll(struct kunit *test, const char *delim) 450 { 451 numbers_list_fix_width(unsigned long long, "%llu", delim, 20, "llu", check_ull); 452 numbers_list_fix_width(long long, "%lld", delim, 20, "lld", check_ll); 453 numbers_list_fix_width(long long, "%lld", delim, 20, "lli", check_ll); 454 numbers_list_fix_width(unsigned long long, "%llx", delim, 16, "llx", check_ull); 455 numbers_list_fix_width(unsigned long long, "0x%llx", delim, 18, "llx", check_ull); 456 numbers_list_fix_width(long long, "0x%llx", delim, 18, "lli", check_ll); 457 } 458 459 static void numbers_list_field_width_l(struct kunit *test, const char *delim) 460 { 461 #if BITS_PER_LONG == 64 462 numbers_list_fix_width(unsigned long, "%lu", delim, 20, "lu", check_ulong); 463 numbers_list_fix_width(long, "%ld", delim, 20, "ld", check_long); 464 numbers_list_fix_width(long, "%ld", delim, 20, "li", check_long); 465 numbers_list_fix_width(unsigned long, "%lx", delim, 16, "lx", check_ulong); 466 numbers_list_fix_width(unsigned long, "0x%lx", delim, 18, "lx", check_ulong); 467 numbers_list_fix_width(long, "0x%lx", delim, 18, "li", check_long); 468 #else 469 numbers_list_fix_width(unsigned long, "%lu", delim, 10, "lu", check_ulong); 470 numbers_list_fix_width(long, "%ld", delim, 11, "ld", check_long); 471 numbers_list_fix_width(long, "%ld", delim, 11, "li", check_long); 472 numbers_list_fix_width(unsigned long, "%lx", delim, 8, "lx", check_ulong); 473 numbers_list_fix_width(unsigned long, "0x%lx", delim, 10, "lx", check_ulong); 474 numbers_list_fix_width(long, "0x%lx", delim, 10, "li", check_long); 475 #endif 476 } 477 478 static void numbers_list_field_width_d(struct kunit *test, const char *delim) 479 { 480 numbers_list_fix_width(unsigned int, "%u", delim, 10, "u", check_uint); 481 numbers_list_fix_width(int, "%d", delim, 11, "d", check_int); 482 numbers_list_fix_width(int, "%d", delim, 11, "i", check_int); 483 numbers_list_fix_width(unsigned int, "%x", delim, 8, "x", check_uint); 484 numbers_list_fix_width(unsigned int, "0x%x", delim, 10, "x", check_uint); 485 numbers_list_fix_width(int, "0x%x", delim, 10, "i", check_int); 486 } 487 488 static void numbers_list_field_width_h(struct kunit *test, const char *delim) 489 { 490 numbers_list_fix_width(unsigned short, "%hu", delim, 5, "hu", check_ushort); 491 numbers_list_fix_width(short, "%hd", delim, 6, "hd", check_short); 492 numbers_list_fix_width(short, "%hd", delim, 6, "hi", check_short); 493 numbers_list_fix_width(unsigned short, "%hx", delim, 4, "hx", check_ushort); 494 numbers_list_fix_width(unsigned short, "0x%hx", delim, 6, "hx", check_ushort); 495 numbers_list_fix_width(short, "0x%hx", delim, 6, "hi", check_short); 496 } 497 498 static void numbers_list_field_width_hh(struct kunit *test, const char *delim) 499 { 500 numbers_list_fix_width(unsigned char, "%hhu", delim, 3, "hhu", check_uchar); 501 numbers_list_fix_width(signed char, "%hhd", delim, 4, "hhd", check_char); 502 numbers_list_fix_width(signed char, "%hhd", delim, 4, "hhi", check_char); 503 numbers_list_fix_width(unsigned char, "%hhx", delim, 2, "hhx", check_uchar); 504 numbers_list_fix_width(unsigned char, "0x%hhx", delim, 4, "hhx", check_uchar); 505 numbers_list_fix_width(signed char, "0x%hhx", delim, 4, "hhi", check_char); 506 } 507 508 /* 509 * List of numbers separated by delim. Each field width specifier is the 510 * maximum possible digits for the given type and base. 511 */ 512 static void numbers_list_field_width_typemax(struct kunit *test) 513 { 514 const char * const *param = test->param_value; 515 const char *delim = *param; 516 517 numbers_list_field_width_ll(test, delim); 518 numbers_list_field_width_l(test, delim); 519 numbers_list_field_width_d(test, delim); 520 numbers_list_field_width_h(test, delim); 521 numbers_list_field_width_hh(test, delim); 522 } 523 524 static void numbers_list_field_width_val_ll(struct kunit *test, const char *delim) 525 { 526 numbers_list_val_width(unsigned long long, "%llu", delim, "llu", check_ull); 527 numbers_list_val_width(long long, "%lld", delim, "lld", check_ll); 528 numbers_list_val_width(long long, "%lld", delim, "lli", check_ll); 529 numbers_list_val_width(unsigned long long, "%llx", delim, "llx", check_ull); 530 numbers_list_val_width(unsigned long long, "0x%llx", delim, "llx", check_ull); 531 numbers_list_val_width(long long, "0x%llx", delim, "lli", check_ll); 532 } 533 534 static void numbers_list_field_width_val_l(struct kunit *test, const char *delim) 535 { 536 numbers_list_val_width(unsigned long, "%lu", delim, "lu", check_ulong); 537 numbers_list_val_width(long, "%ld", delim, "ld", check_long); 538 numbers_list_val_width(long, "%ld", delim, "li", check_long); 539 numbers_list_val_width(unsigned long, "%lx", delim, "lx", check_ulong); 540 numbers_list_val_width(unsigned long, "0x%lx", delim, "lx", check_ulong); 541 numbers_list_val_width(long, "0x%lx", delim, "li", check_long); 542 } 543 544 static void numbers_list_field_width_val_d(struct kunit *test, const char *delim) 545 { 546 numbers_list_val_width(unsigned int, "%u", delim, "u", check_uint); 547 numbers_list_val_width(int, "%d", delim, "d", check_int); 548 numbers_list_val_width(int, "%d", delim, "i", check_int); 549 numbers_list_val_width(unsigned int, "%x", delim, "x", check_uint); 550 numbers_list_val_width(unsigned int, "0x%x", delim, "x", check_uint); 551 numbers_list_val_width(int, "0x%x", delim, "i", check_int); 552 } 553 554 static void numbers_list_field_width_val_h(struct kunit *test, const char *delim) 555 { 556 numbers_list_val_width(unsigned short, "%hu", delim, "hu", check_ushort); 557 numbers_list_val_width(short, "%hd", delim, "hd", check_short); 558 numbers_list_val_width(short, "%hd", delim, "hi", check_short); 559 numbers_list_val_width(unsigned short, "%hx", delim, "hx", check_ushort); 560 numbers_list_val_width(unsigned short, "0x%hx", delim, "hx", check_ushort); 561 numbers_list_val_width(short, "0x%hx", delim, "hi", check_short); 562 } 563 564 static void numbers_list_field_width_val_hh(struct kunit *test, const char *delim) 565 { 566 numbers_list_val_width(unsigned char, "%hhu", delim, "hhu", check_uchar); 567 numbers_list_val_width(signed char, "%hhd", delim, "hhd", check_char); 568 numbers_list_val_width(signed char, "%hhd", delim, "hhi", check_char); 569 numbers_list_val_width(unsigned char, "%hhx", delim, "hhx", check_uchar); 570 numbers_list_val_width(unsigned char, "0x%hhx", delim, "hhx", check_uchar); 571 numbers_list_val_width(signed char, "0x%hhx", delim, "hhi", check_char); 572 } 573 574 /* 575 * List of numbers separated by delim. Each field width specifier is the 576 * exact length of the corresponding value digits in the string being scanned. 577 */ 578 static void numbers_list_field_width_val_width(struct kunit *test) 579 { 580 const char * const *param = test->param_value; 581 const char *delim = *param; 582 583 numbers_list_field_width_val_ll(test, delim); 584 numbers_list_field_width_val_l(test, delim); 585 numbers_list_field_width_val_d(test, delim); 586 numbers_list_field_width_val_h(test, delim); 587 numbers_list_field_width_val_hh(test, delim); 588 } 589 590 /* 591 * Slice a continuous string of digits without field delimiters, containing 592 * numbers of varying length, using the field width to extract each group 593 * of digits. For example the hex values c0,3,bf01,303 would have a 594 * string representation of "c03bf01303" and extracted with "%2x%1x%4x%3x". 595 */ 596 static void numbers_slice(struct kunit *test) 597 { 598 const char *delim = ""; 599 600 KUNIT_ASSERT_PTR_EQ(test, test->param_value, NULL); 601 test->param_value = &delim; 602 603 numbers_list_field_width_val_width(test); 604 } 605 606 #define test_number_prefix(T, str, scan_fmt, expect0, expect1, n_args, fn) \ 607 do { \ 608 const T expect[2] = { expect0, expect1 }; \ 609 T result[2] = { (T)~expect[0], (T)~expect[1] }; \ 610 \ 611 _test(test, __FILE__, __LINE__, fn, &expect, str, scan_fmt, n_args, &result[0], &result[1]);\ 612 } while (0) 613 614 /* 615 * Number prefix is >= field width. 616 * Expected behaviour is derived from testing userland sscanf. 617 */ 618 static void numbers_prefix_overflow(struct kunit *test) 619 { 620 /* 621 * Negative decimal with a field of width 1, should quit scanning 622 * and return 0. 623 */ 624 test_number_prefix(long long, "-1 1", "%1lld %lld", 0, 0, 0, check_ll); 625 test_number_prefix(long, "-1 1", "%1ld %ld", 0, 0, 0, check_long); 626 test_number_prefix(int, "-1 1", "%1d %d", 0, 0, 0, check_int); 627 test_number_prefix(short, "-1 1", "%1hd %hd", 0, 0, 0, check_short); 628 test_number_prefix(signed char, "-1 1", "%1hhd %hhd", 0, 0, 0, check_char); 629 630 test_number_prefix(long long, "-1 1", "%1lli %lli", 0, 0, 0, check_ll); 631 test_number_prefix(long, "-1 1", "%1li %li", 0, 0, 0, check_long); 632 test_number_prefix(int, "-1 1", "%1i %i", 0, 0, 0, check_int); 633 test_number_prefix(short, "-1 1", "%1hi %hi", 0, 0, 0, check_short); 634 test_number_prefix(signed char, "-1 1", "%1hhi %hhi", 0, 0, 0, check_char); 635 636 /* 637 * 0x prefix in a field of width 1: 0 is a valid digit so should 638 * convert. Next field scan starts at the 'x' which isn't a digit so 639 * scan quits with one field converted. 640 */ 641 test_number_prefix(unsigned long long, "0xA7", "%1llx%llx", 0, 0, 1, check_ull); 642 test_number_prefix(unsigned long, "0xA7", "%1lx%lx", 0, 0, 1, check_ulong); 643 test_number_prefix(unsigned int, "0xA7", "%1x%x", 0, 0, 1, check_uint); 644 test_number_prefix(unsigned short, "0xA7", "%1hx%hx", 0, 0, 1, check_ushort); 645 test_number_prefix(unsigned char, "0xA7", "%1hhx%hhx", 0, 0, 1, check_uchar); 646 test_number_prefix(long long, "0xA7", "%1lli%llx", 0, 0, 1, check_ll); 647 test_number_prefix(long, "0xA7", "%1li%lx", 0, 0, 1, check_long); 648 test_number_prefix(int, "0xA7", "%1i%x", 0, 0, 1, check_int); 649 test_number_prefix(short, "0xA7", "%1hi%hx", 0, 0, 1, check_short); 650 test_number_prefix(char, "0xA7", "%1hhi%hhx", 0, 0, 1, check_char); 651 652 /* 653 * 0x prefix in a field of width 2 using %x conversion: first field 654 * converts to 0. Next field scan starts at the character after "0x". 655 * Both fields will convert. 656 */ 657 test_number_prefix(unsigned long long, "0xA7", "%2llx%llx", 0, 0xa7, 2, check_ull); 658 test_number_prefix(unsigned long, "0xA7", "%2lx%lx", 0, 0xa7, 2, check_ulong); 659 test_number_prefix(unsigned int, "0xA7", "%2x%x", 0, 0xa7, 2, check_uint); 660 test_number_prefix(unsigned short, "0xA7", "%2hx%hx", 0, 0xa7, 2, check_ushort); 661 test_number_prefix(unsigned char, "0xA7", "%2hhx%hhx", 0, 0xa7, 2, check_uchar); 662 663 /* 664 * 0x prefix in a field of width 2 using %i conversion: first field 665 * converts to 0. Next field scan starts at the character after "0x", 666 * which will convert if can be interpreted as decimal but will fail 667 * if it contains any hex digits (since no 0x prefix). 668 */ 669 test_number_prefix(long long, "0x67", "%2lli%lli", 0, 67, 2, check_ll); 670 test_number_prefix(long, "0x67", "%2li%li", 0, 67, 2, check_long); 671 test_number_prefix(int, "0x67", "%2i%i", 0, 67, 2, check_int); 672 test_number_prefix(short, "0x67", "%2hi%hi", 0, 67, 2, check_short); 673 test_number_prefix(char, "0x67", "%2hhi%hhi", 0, 67, 2, check_char); 674 675 test_number_prefix(long long, "0xA7", "%2lli%lli", 0, 0, 1, check_ll); 676 test_number_prefix(long, "0xA7", "%2li%li", 0, 0, 1, check_long); 677 test_number_prefix(int, "0xA7", "%2i%i", 0, 0, 1, check_int); 678 test_number_prefix(short, "0xA7", "%2hi%hi", 0, 0, 1, check_short); 679 test_number_prefix(char, "0xA7", "%2hhi%hhi", 0, 0, 1, check_char); 680 } 681 682 #define _test_simple_strtoxx(T, fn, gen_fmt, expect, base) \ 683 do { \ 684 T got; \ 685 char *endp; \ 686 int len; \ 687 \ 688 len = snprintf(test_buffer, BUF_SIZE, gen_fmt, expect); \ 689 got = (fn)(test_buffer, &endp, base); \ 690 if (got != (expect)) { \ 691 KUNIT_FAIL(test, #fn "(\"%s\", %d): got " gen_fmt " expected " gen_fmt, \ 692 test_buffer, base, got, expect); \ 693 } else if (endp != test_buffer + len) { \ 694 KUNIT_FAIL(test, #fn "(\"%s\", %d) startp=0x%px got endp=0x%px expected 0x%px", \ 695 test_buffer, base, test_buffer, \ 696 test_buffer + len, endp); \ 697 } \ 698 } while (0) 699 700 #define test_simple_strtoxx(T, fn, gen_fmt, base) \ 701 do { \ 702 int i; \ 703 \ 704 for (i = 0; i < ARRAY_SIZE(numbers); i++) { \ 705 _test_simple_strtoxx(T, fn, gen_fmt, (T)numbers[i], base); \ 706 \ 707 if (is_signed_type(T)) \ 708 _test_simple_strtoxx(T, fn, gen_fmt, \ 709 -(T)numbers[i], base); \ 710 } \ 711 } while (0) 712 713 static void test_simple_strtoull(struct kunit *test) 714 { 715 test_simple_strtoxx(unsigned long long, simple_strtoull, "%llu", 10); 716 test_simple_strtoxx(unsigned long long, simple_strtoull, "%llu", 0); 717 test_simple_strtoxx(unsigned long long, simple_strtoull, "%llx", 16); 718 test_simple_strtoxx(unsigned long long, simple_strtoull, "0x%llx", 16); 719 test_simple_strtoxx(unsigned long long, simple_strtoull, "0x%llx", 0); 720 } 721 722 static void test_simple_strtoll(struct kunit *test) 723 { 724 test_simple_strtoxx(long long, simple_strtoll, "%lld", 10); 725 test_simple_strtoxx(long long, simple_strtoll, "%lld", 0); 726 test_simple_strtoxx(long long, simple_strtoll, "%llx", 16); 727 test_simple_strtoxx(long long, simple_strtoll, "0x%llx", 16); 728 test_simple_strtoxx(long long, simple_strtoll, "0x%llx", 0); 729 } 730 731 static void test_simple_strtoul(struct kunit *test) 732 { 733 test_simple_strtoxx(unsigned long, simple_strtoul, "%lu", 10); 734 test_simple_strtoxx(unsigned long, simple_strtoul, "%lu", 0); 735 test_simple_strtoxx(unsigned long, simple_strtoul, "%lx", 16); 736 test_simple_strtoxx(unsigned long, simple_strtoul, "0x%lx", 16); 737 test_simple_strtoxx(unsigned long, simple_strtoul, "0x%lx", 0); 738 } 739 740 static void test_simple_strtol(struct kunit *test) 741 { 742 test_simple_strtoxx(long, simple_strtol, "%ld", 10); 743 test_simple_strtoxx(long, simple_strtol, "%ld", 0); 744 test_simple_strtoxx(long, simple_strtol, "%lx", 16); 745 test_simple_strtoxx(long, simple_strtol, "0x%lx", 16); 746 test_simple_strtoxx(long, simple_strtol, "0x%lx", 0); 747 } 748 749 /* Selection of common delimiters/separators between numbers in a string. */ 750 static const char * const number_delimiters[] = { 751 " ", ":", ",", "-", "/", 752 }; 753 754 static void number_delimiter_param_desc(const char * const *param, 755 char *desc) 756 { 757 snprintf(desc, KUNIT_PARAM_DESC_SIZE, "\"%s\"", *param); 758 } 759 760 KUNIT_ARRAY_PARAM(number_delimiters, number_delimiters, number_delimiter_param_desc); 761 762 static struct kunit_case scanf_test_cases[] = { 763 KUNIT_CASE(numbers_simple), 764 /* String with multiple numbers separated by delimiter. */ 765 KUNIT_CASE_PARAM(numbers_list, number_delimiters_gen_params), 766 /* Field width may be longer than actual field digits. */ 767 KUNIT_CASE_PARAM(numbers_list_field_width_typemax, number_delimiters_gen_params), 768 /* Each field width exactly length of actual field digits. */ 769 KUNIT_CASE_PARAM(numbers_list_field_width_val_width, number_delimiters_gen_params), 770 /* Slice continuous sequence of digits using field widths. */ 771 KUNIT_CASE(numbers_slice), 772 KUNIT_CASE(numbers_prefix_overflow), 773 774 KUNIT_CASE(test_simple_strtoull), 775 KUNIT_CASE(test_simple_strtoll), 776 KUNIT_CASE(test_simple_strtoul), 777 KUNIT_CASE(test_simple_strtol), 778 {} 779 }; 780 781 static int scanf_suite_init(struct kunit_suite *suite) 782 { 783 test_buffer = kmalloc(BUF_SIZE, GFP_KERNEL); 784 if (!test_buffer) 785 return -ENOMEM; 786 787 fmt_buffer = kmalloc(BUF_SIZE, GFP_KERNEL); 788 if (!fmt_buffer) { 789 kfree(test_buffer); 790 return -ENOMEM; 791 } 792 793 prandom_seed_state(&rnd_state, 3141592653589793238ULL); 794 795 return 0; 796 } 797 798 static void scanf_suite_exit(struct kunit_suite *suite) 799 { 800 kfree(fmt_buffer); 801 kfree(test_buffer); 802 } 803 804 static struct kunit_suite scanf_test_suite = { 805 .name = "scanf", 806 .suite_init = scanf_suite_init, 807 .suite_exit = scanf_suite_exit, 808 .test_cases = scanf_test_cases, 809 }; 810 811 kunit_test_suite(scanf_test_suite); 812 813 MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>"); 814 MODULE_DESCRIPTION("Test cases for sscanf facility"); 815 MODULE_LICENSE("GPL v2"); 816