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, const char *delim) 438 { 439 numbers_list_ll(test, delim); 440 numbers_list_l(test, delim); 441 numbers_list_d(test, delim); 442 numbers_list_h(test, delim); 443 numbers_list_hh(test, delim); 444 } 445 446 static void numbers_list_field_width_ll(struct kunit *test, const char *delim) 447 { 448 numbers_list_fix_width(unsigned long long, "%llu", delim, 20, "llu", check_ull); 449 numbers_list_fix_width(long long, "%lld", delim, 20, "lld", check_ll); 450 numbers_list_fix_width(long long, "%lld", delim, 20, "lli", check_ll); 451 numbers_list_fix_width(unsigned long long, "%llx", delim, 16, "llx", check_ull); 452 numbers_list_fix_width(unsigned long long, "0x%llx", delim, 18, "llx", check_ull); 453 numbers_list_fix_width(long long, "0x%llx", delim, 18, "lli", check_ll); 454 } 455 456 static void numbers_list_field_width_l(struct kunit *test, const char *delim) 457 { 458 #if BITS_PER_LONG == 64 459 numbers_list_fix_width(unsigned long, "%lu", delim, 20, "lu", check_ulong); 460 numbers_list_fix_width(long, "%ld", delim, 20, "ld", check_long); 461 numbers_list_fix_width(long, "%ld", delim, 20, "li", check_long); 462 numbers_list_fix_width(unsigned long, "%lx", delim, 16, "lx", check_ulong); 463 numbers_list_fix_width(unsigned long, "0x%lx", delim, 18, "lx", check_ulong); 464 numbers_list_fix_width(long, "0x%lx", delim, 18, "li", check_long); 465 #else 466 numbers_list_fix_width(unsigned long, "%lu", delim, 10, "lu", check_ulong); 467 numbers_list_fix_width(long, "%ld", delim, 11, "ld", check_long); 468 numbers_list_fix_width(long, "%ld", delim, 11, "li", check_long); 469 numbers_list_fix_width(unsigned long, "%lx", delim, 8, "lx", check_ulong); 470 numbers_list_fix_width(unsigned long, "0x%lx", delim, 10, "lx", check_ulong); 471 numbers_list_fix_width(long, "0x%lx", delim, 10, "li", check_long); 472 #endif 473 } 474 475 static void numbers_list_field_width_d(struct kunit *test, const char *delim) 476 { 477 numbers_list_fix_width(unsigned int, "%u", delim, 10, "u", check_uint); 478 numbers_list_fix_width(int, "%d", delim, 11, "d", check_int); 479 numbers_list_fix_width(int, "%d", delim, 11, "i", check_int); 480 numbers_list_fix_width(unsigned int, "%x", delim, 8, "x", check_uint); 481 numbers_list_fix_width(unsigned int, "0x%x", delim, 10, "x", check_uint); 482 numbers_list_fix_width(int, "0x%x", delim, 10, "i", check_int); 483 } 484 485 static void numbers_list_field_width_h(struct kunit *test, const char *delim) 486 { 487 numbers_list_fix_width(unsigned short, "%hu", delim, 5, "hu", check_ushort); 488 numbers_list_fix_width(short, "%hd", delim, 6, "hd", check_short); 489 numbers_list_fix_width(short, "%hd", delim, 6, "hi", check_short); 490 numbers_list_fix_width(unsigned short, "%hx", delim, 4, "hx", check_ushort); 491 numbers_list_fix_width(unsigned short, "0x%hx", delim, 6, "hx", check_ushort); 492 numbers_list_fix_width(short, "0x%hx", delim, 6, "hi", check_short); 493 } 494 495 static void numbers_list_field_width_hh(struct kunit *test, const char *delim) 496 { 497 numbers_list_fix_width(unsigned char, "%hhu", delim, 3, "hhu", check_uchar); 498 numbers_list_fix_width(signed char, "%hhd", delim, 4, "hhd", check_char); 499 numbers_list_fix_width(signed char, "%hhd", delim, 4, "hhi", check_char); 500 numbers_list_fix_width(unsigned char, "%hhx", delim, 2, "hhx", check_uchar); 501 numbers_list_fix_width(unsigned char, "0x%hhx", delim, 4, "hhx", check_uchar); 502 numbers_list_fix_width(signed char, "0x%hhx", delim, 4, "hhi", check_char); 503 } 504 505 /* 506 * List of numbers separated by delim. Each field width specifier is the 507 * maximum possible digits for the given type and base. 508 */ 509 static void numbers_list_field_width_typemax(struct kunit *test, const char *delim) 510 { 511 numbers_list_field_width_ll(test, delim); 512 numbers_list_field_width_l(test, delim); 513 numbers_list_field_width_d(test, delim); 514 numbers_list_field_width_h(test, delim); 515 numbers_list_field_width_hh(test, delim); 516 } 517 518 static void numbers_list_field_width_val_ll(struct kunit *test, const char *delim) 519 { 520 numbers_list_val_width(unsigned long long, "%llu", delim, "llu", check_ull); 521 numbers_list_val_width(long long, "%lld", delim, "lld", check_ll); 522 numbers_list_val_width(long long, "%lld", delim, "lli", check_ll); 523 numbers_list_val_width(unsigned long long, "%llx", delim, "llx", check_ull); 524 numbers_list_val_width(unsigned long long, "0x%llx", delim, "llx", check_ull); 525 numbers_list_val_width(long long, "0x%llx", delim, "lli", check_ll); 526 } 527 528 static void numbers_list_field_width_val_l(struct kunit *test, const char *delim) 529 { 530 numbers_list_val_width(unsigned long, "%lu", delim, "lu", check_ulong); 531 numbers_list_val_width(long, "%ld", delim, "ld", check_long); 532 numbers_list_val_width(long, "%ld", delim, "li", check_long); 533 numbers_list_val_width(unsigned long, "%lx", delim, "lx", check_ulong); 534 numbers_list_val_width(unsigned long, "0x%lx", delim, "lx", check_ulong); 535 numbers_list_val_width(long, "0x%lx", delim, "li", check_long); 536 } 537 538 static void numbers_list_field_width_val_d(struct kunit *test, const char *delim) 539 { 540 numbers_list_val_width(unsigned int, "%u", delim, "u", check_uint); 541 numbers_list_val_width(int, "%d", delim, "d", check_int); 542 numbers_list_val_width(int, "%d", delim, "i", check_int); 543 numbers_list_val_width(unsigned int, "%x", delim, "x", check_uint); 544 numbers_list_val_width(unsigned int, "0x%x", delim, "x", check_uint); 545 numbers_list_val_width(int, "0x%x", delim, "i", check_int); 546 } 547 548 static void numbers_list_field_width_val_h(struct kunit *test, const char *delim) 549 { 550 numbers_list_val_width(unsigned short, "%hu", delim, "hu", check_ushort); 551 numbers_list_val_width(short, "%hd", delim, "hd", check_short); 552 numbers_list_val_width(short, "%hd", delim, "hi", check_short); 553 numbers_list_val_width(unsigned short, "%hx", delim, "hx", check_ushort); 554 numbers_list_val_width(unsigned short, "0x%hx", delim, "hx", check_ushort); 555 numbers_list_val_width(short, "0x%hx", delim, "hi", check_short); 556 } 557 558 static void numbers_list_field_width_val_hh(struct kunit *test, const char *delim) 559 { 560 numbers_list_val_width(unsigned char, "%hhu", delim, "hhu", check_uchar); 561 numbers_list_val_width(signed char, "%hhd", delim, "hhd", check_char); 562 numbers_list_val_width(signed char, "%hhd", delim, "hhi", check_char); 563 numbers_list_val_width(unsigned char, "%hhx", delim, "hhx", check_uchar); 564 numbers_list_val_width(unsigned char, "0x%hhx", delim, "hhx", check_uchar); 565 numbers_list_val_width(signed char, "0x%hhx", delim, "hhi", check_char); 566 } 567 568 /* 569 * List of numbers separated by delim. Each field width specifier is the 570 * exact length of the corresponding value digits in the string being scanned. 571 */ 572 static void numbers_list_field_width_val_width(struct kunit *test, const char *delim) 573 { 574 numbers_list_field_width_val_ll(test, delim); 575 numbers_list_field_width_val_l(test, delim); 576 numbers_list_field_width_val_d(test, delim); 577 numbers_list_field_width_val_h(test, delim); 578 numbers_list_field_width_val_hh(test, delim); 579 } 580 581 /* 582 * Slice a continuous string of digits without field delimiters, containing 583 * numbers of varying length, using the field width to extract each group 584 * of digits. For example the hex values c0,3,bf01,303 would have a 585 * string representation of "c03bf01303" and extracted with "%2x%1x%4x%3x". 586 */ 587 static void numbers_slice(struct kunit *test) 588 { 589 numbers_list_field_width_val_width(test, ""); 590 } 591 592 #define test_number_prefix(T, str, scan_fmt, expect0, expect1, n_args, fn) \ 593 do { \ 594 const T expect[2] = { expect0, expect1 }; \ 595 T result[2] = { (T)~expect[0], (T)~expect[1] }; \ 596 \ 597 _test(test, __FILE__, __LINE__, fn, &expect, str, scan_fmt, n_args, &result[0], &result[1]);\ 598 } while (0) 599 600 /* 601 * Number prefix is >= field width. 602 * Expected behaviour is derived from testing userland sscanf. 603 */ 604 static void numbers_prefix_overflow(struct kunit *test) 605 { 606 /* 607 * Negative decimal with a field of width 1, should quit scanning 608 * and return 0. 609 */ 610 test_number_prefix(long long, "-1 1", "%1lld %lld", 0, 0, 0, check_ll); 611 test_number_prefix(long, "-1 1", "%1ld %ld", 0, 0, 0, check_long); 612 test_number_prefix(int, "-1 1", "%1d %d", 0, 0, 0, check_int); 613 test_number_prefix(short, "-1 1", "%1hd %hd", 0, 0, 0, check_short); 614 test_number_prefix(signed char, "-1 1", "%1hhd %hhd", 0, 0, 0, check_char); 615 616 test_number_prefix(long long, "-1 1", "%1lli %lli", 0, 0, 0, check_ll); 617 test_number_prefix(long, "-1 1", "%1li %li", 0, 0, 0, check_long); 618 test_number_prefix(int, "-1 1", "%1i %i", 0, 0, 0, check_int); 619 test_number_prefix(short, "-1 1", "%1hi %hi", 0, 0, 0, check_short); 620 test_number_prefix(signed char, "-1 1", "%1hhi %hhi", 0, 0, 0, check_char); 621 622 /* 623 * 0x prefix in a field of width 1: 0 is a valid digit so should 624 * convert. Next field scan starts at the 'x' which isn't a digit so 625 * scan quits with one field converted. 626 */ 627 test_number_prefix(unsigned long long, "0xA7", "%1llx%llx", 0, 0, 1, check_ull); 628 test_number_prefix(unsigned long, "0xA7", "%1lx%lx", 0, 0, 1, check_ulong); 629 test_number_prefix(unsigned int, "0xA7", "%1x%x", 0, 0, 1, check_uint); 630 test_number_prefix(unsigned short, "0xA7", "%1hx%hx", 0, 0, 1, check_ushort); 631 test_number_prefix(unsigned char, "0xA7", "%1hhx%hhx", 0, 0, 1, check_uchar); 632 test_number_prefix(long long, "0xA7", "%1lli%llx", 0, 0, 1, check_ll); 633 test_number_prefix(long, "0xA7", "%1li%lx", 0, 0, 1, check_long); 634 test_number_prefix(int, "0xA7", "%1i%x", 0, 0, 1, check_int); 635 test_number_prefix(short, "0xA7", "%1hi%hx", 0, 0, 1, check_short); 636 test_number_prefix(char, "0xA7", "%1hhi%hhx", 0, 0, 1, check_char); 637 638 /* 639 * 0x prefix in a field of width 2 using %x conversion: first field 640 * converts to 0. Next field scan starts at the character after "0x". 641 * Both fields will convert. 642 */ 643 test_number_prefix(unsigned long long, "0xA7", "%2llx%llx", 0, 0xa7, 2, check_ull); 644 test_number_prefix(unsigned long, "0xA7", "%2lx%lx", 0, 0xa7, 2, check_ulong); 645 test_number_prefix(unsigned int, "0xA7", "%2x%x", 0, 0xa7, 2, check_uint); 646 test_number_prefix(unsigned short, "0xA7", "%2hx%hx", 0, 0xa7, 2, check_ushort); 647 test_number_prefix(unsigned char, "0xA7", "%2hhx%hhx", 0, 0xa7, 2, check_uchar); 648 649 /* 650 * 0x prefix in a field of width 2 using %i conversion: first field 651 * converts to 0. Next field scan starts at the character after "0x", 652 * which will convert if can be interpreted as decimal but will fail 653 * if it contains any hex digits (since no 0x prefix). 654 */ 655 test_number_prefix(long long, "0x67", "%2lli%lli", 0, 67, 2, check_ll); 656 test_number_prefix(long, "0x67", "%2li%li", 0, 67, 2, check_long); 657 test_number_prefix(int, "0x67", "%2i%i", 0, 67, 2, check_int); 658 test_number_prefix(short, "0x67", "%2hi%hi", 0, 67, 2, check_short); 659 test_number_prefix(char, "0x67", "%2hhi%hhi", 0, 67, 2, check_char); 660 661 test_number_prefix(long long, "0xA7", "%2lli%lli", 0, 0, 1, check_ll); 662 test_number_prefix(long, "0xA7", "%2li%li", 0, 0, 1, check_long); 663 test_number_prefix(int, "0xA7", "%2i%i", 0, 0, 1, check_int); 664 test_number_prefix(short, "0xA7", "%2hi%hi", 0, 0, 1, check_short); 665 test_number_prefix(char, "0xA7", "%2hhi%hhi", 0, 0, 1, check_char); 666 } 667 668 #define _test_simple_strtoxx(T, fn, gen_fmt, expect, base) \ 669 do { \ 670 T got; \ 671 char *endp; \ 672 int len; \ 673 \ 674 len = snprintf(test_buffer, BUF_SIZE, gen_fmt, expect); \ 675 got = (fn)(test_buffer, &endp, base); \ 676 if (got != (expect)) { \ 677 KUNIT_FAIL(test, #fn "(\"%s\", %d): got " gen_fmt " expected " gen_fmt, \ 678 test_buffer, base, got, expect); \ 679 } else if (endp != test_buffer + len) { \ 680 KUNIT_FAIL(test, #fn "(\"%s\", %d) startp=0x%px got endp=0x%px expected 0x%px", \ 681 test_buffer, base, test_buffer, \ 682 test_buffer + len, endp); \ 683 } \ 684 } while (0) 685 686 #define test_simple_strtoxx(T, fn, gen_fmt, base) \ 687 do { \ 688 int i; \ 689 \ 690 for (i = 0; i < ARRAY_SIZE(numbers); i++) { \ 691 _test_simple_strtoxx(T, fn, gen_fmt, (T)numbers[i], base); \ 692 \ 693 if (is_signed_type(T)) \ 694 _test_simple_strtoxx(T, fn, gen_fmt, \ 695 -(T)numbers[i], base); \ 696 } \ 697 } while (0) 698 699 static void test_simple_strtoull(struct kunit *test) 700 { 701 test_simple_strtoxx(unsigned long long, simple_strtoull, "%llu", 10); 702 test_simple_strtoxx(unsigned long long, simple_strtoull, "%llu", 0); 703 test_simple_strtoxx(unsigned long long, simple_strtoull, "%llx", 16); 704 test_simple_strtoxx(unsigned long long, simple_strtoull, "0x%llx", 16); 705 test_simple_strtoxx(unsigned long long, simple_strtoull, "0x%llx", 0); 706 } 707 708 static void test_simple_strtoll(struct kunit *test) 709 { 710 test_simple_strtoxx(long long, simple_strtoll, "%lld", 10); 711 test_simple_strtoxx(long long, simple_strtoll, "%lld", 0); 712 test_simple_strtoxx(long long, simple_strtoll, "%llx", 16); 713 test_simple_strtoxx(long long, simple_strtoll, "0x%llx", 16); 714 test_simple_strtoxx(long long, simple_strtoll, "0x%llx", 0); 715 } 716 717 static void test_simple_strtoul(struct kunit *test) 718 { 719 test_simple_strtoxx(unsigned long, simple_strtoul, "%lu", 10); 720 test_simple_strtoxx(unsigned long, simple_strtoul, "%lu", 0); 721 test_simple_strtoxx(unsigned long, simple_strtoul, "%lx", 16); 722 test_simple_strtoxx(unsigned long, simple_strtoul, "0x%lx", 16); 723 test_simple_strtoxx(unsigned long, simple_strtoul, "0x%lx", 0); 724 } 725 726 static void test_simple_strtol(struct kunit *test) 727 { 728 test_simple_strtoxx(long, simple_strtol, "%ld", 10); 729 test_simple_strtoxx(long, simple_strtol, "%ld", 0); 730 test_simple_strtoxx(long, simple_strtol, "%lx", 16); 731 test_simple_strtoxx(long, simple_strtol, "0x%lx", 16); 732 test_simple_strtoxx(long, simple_strtol, "0x%lx", 0); 733 } 734 735 /* Selection of common delimiters/separators between numbers in a string. */ 736 static const char * const number_delimiters[] = { 737 " ", ":", ",", "-", "/", 738 }; 739 740 static void test_numbers(struct kunit *test) 741 { 742 int i; 743 744 /* String containing only one number. */ 745 numbers_simple(test); 746 747 /* String with multiple numbers separated by delimiter. */ 748 for (i = 0; i < ARRAY_SIZE(number_delimiters); i++) { 749 numbers_list(test, number_delimiters[i]); 750 751 /* Field width may be longer than actual field digits. */ 752 numbers_list_field_width_typemax(test, number_delimiters[i]); 753 754 /* Each field width exactly length of actual field digits. */ 755 numbers_list_field_width_val_width(test, number_delimiters[i]); 756 } 757 758 /* Slice continuous sequence of digits using field widths. */ 759 numbers_slice(test); 760 761 numbers_prefix_overflow(test); 762 } 763 764 static void scanf_test(struct kunit *test) 765 { 766 test_buffer = kmalloc(BUF_SIZE, GFP_KERNEL); 767 if (!test_buffer) 768 return; 769 770 fmt_buffer = kmalloc(BUF_SIZE, GFP_KERNEL); 771 if (!fmt_buffer) { 772 kfree(test_buffer); 773 return; 774 } 775 776 prandom_seed_state(&rnd_state, 3141592653589793238ULL); 777 778 test_numbers(test); 779 780 test_simple_strtoull(test); 781 test_simple_strtoll(test); 782 test_simple_strtoul(test); 783 test_simple_strtol(test); 784 785 kfree(fmt_buffer); 786 kfree(test_buffer); 787 } 788 789 static struct kunit_case scanf_test_cases[] = { 790 KUNIT_CASE(scanf_test), 791 {} 792 }; 793 794 static struct kunit_suite scanf_test_suite = { 795 .name = "scanf", 796 .test_cases = scanf_test_cases, 797 }; 798 799 kunit_test_suite(scanf_test_suite); 800 801 MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>"); 802 MODULE_DESCRIPTION("Test cases for sscanf facility"); 803 MODULE_LICENSE("GPL v2"); 804