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