Merge tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso...
[linux-2.6-microblaze.git] / lib / test_scanf.c
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) & GENMASK(n_bits, 0);
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 & GENMASK_ULL(n_bits, 0);
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");