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