test_scanf.c 29 KB

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