]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - lib/test_hexdump.c
test_hexdump: introduce test_hexdump_prepare_test() helper
[mirror_ubuntu-bionic-kernel.git] / lib / test_hexdump.c
CommitLineData
64d1d77a
AS
1/*
2 * Test cases for lib/hexdump.c module.
3 */
4#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
5
6#include <linux/init.h>
7#include <linux/kernel.h>
8#include <linux/module.h>
9#include <linux/random.h>
10#include <linux/string.h>
11
12static const unsigned char data_b[] = {
13 '\xbe', '\x32', '\xdb', '\x7b', '\x0a', '\x18', '\x93', '\xb2', /* 00 - 07 */
14 '\x70', '\xba', '\xc4', '\x24', '\x7d', '\x83', '\x34', '\x9b', /* 08 - 0f */
15 '\xa6', '\x9c', '\x31', '\xad', '\x9c', '\x0f', '\xac', '\xe9', /* 10 - 17 */
16 '\x4c', '\xd1', '\x19', '\x99', '\x43', '\xb1', '\xaf', '\x0c', /* 18 - 1f */
17};
18
19static const unsigned char data_a[] = ".2.{....p..$}.4...1.....L...C...";
20
c79574ab 21static const char * const test_data_1_le[] __initconst = {
64d1d77a
AS
22 "be", "32", "db", "7b", "0a", "18", "93", "b2",
23 "70", "ba", "c4", "24", "7d", "83", "34", "9b",
24 "a6", "9c", "31", "ad", "9c", "0f", "ac", "e9",
25 "4c", "d1", "19", "99", "43", "b1", "af", "0c",
26};
27
79e23d57 28static const char * const test_data_2_le[] __initconst = {
64d1d77a
AS
29 "32be", "7bdb", "180a", "b293",
30 "ba70", "24c4", "837d", "9b34",
31 "9ca6", "ad31", "0f9c", "e9ac",
32 "d14c", "9919", "b143", "0caf",
33};
34
79e23d57 35static const char * const test_data_4_le[] __initconst = {
64d1d77a
AS
36 "7bdb32be", "b293180a", "24c4ba70", "9b34837d",
37 "ad319ca6", "e9ac0f9c", "9919d14c", "0cafb143",
38};
39
79e23d57 40static const char * const test_data_8_le[] __initconst = {
64d1d77a
AS
41 "b293180a7bdb32be", "9b34837d24c4ba70",
42 "e9ac0f9cad319ca6", "0cafb1439919d14c",
43};
44
87977ca6
AS
45static void __init test_hexdump_prepare_test(size_t len, int rowsize,
46 int groupsize, char *test,
47 size_t testlen, bool ascii)
64d1d77a 48{
64d1d77a 49 char *p;
17974c05 50 const char * const *result;
64d1d77a
AS
51 size_t l = len;
52 int gs = groupsize, rs = rowsize;
53 unsigned int i;
54
64d1d77a
AS
55 if (rs != 16 && rs != 32)
56 rs = 16;
57
58 if (l > rs)
59 l = rs;
60
61 if (!is_power_of_2(gs) || gs > 8 || (len % gs != 0))
62 gs = 1;
63
64 if (gs == 8)
65 result = test_data_8_le;
66 else if (gs == 4)
67 result = test_data_4_le;
68 else if (gs == 2)
69 result = test_data_2_le;
70 else
71 result = test_data_1_le;
72
87977ca6 73 memset(test, ' ', testlen);
64d1d77a
AS
74
75 /* hex dump */
76 p = test;
77 for (i = 0; i < l / gs; i++) {
78 const char *q = *result++;
79 size_t amount = strlen(q);
80
81 strncpy(p, q, amount);
82 p += amount + 1;
83 }
84 if (i)
85 p--;
86
87 /* ASCII part */
88 if (ascii) {
89 p = test + rs * 2 + rs / gs + 1;
90 strncpy(p, data_a, l);
91 p += l;
92 }
93
94 *p = '\0';
87977ca6
AS
95}
96
97#define TEST_HEXDUMP_BUF_SIZE (32 * 3 + 2 + 32 + 1)
98
99static void __init test_hexdump(size_t len, int rowsize, int groupsize,
100 bool ascii)
101{
102 char test[TEST_HEXDUMP_BUF_SIZE];
103 char real[TEST_HEXDUMP_BUF_SIZE];
104
105 hex_dump_to_buffer(data_b, len, rowsize, groupsize, real, sizeof(real),
106 ascii);
107
108 test_hexdump_prepare_test(len, rowsize, groupsize, test, sizeof(test),
109 ascii);
64d1d77a
AS
110
111 if (strcmp(test, real)) {
112 pr_err("Len: %zu row: %d group: %d\n", len, rowsize, groupsize);
113 pr_err("Result: '%s'\n", real);
114 pr_err("Expect: '%s'\n", test);
115 }
116}
117
118static void __init test_hexdump_set(int rowsize, bool ascii)
119{
120 size_t d = min_t(size_t, sizeof(data_b), rowsize);
121 size_t len = get_random_int() % d + 1;
122
123 test_hexdump(len, rowsize, 4, ascii);
124 test_hexdump(len, rowsize, 2, ascii);
125 test_hexdump(len, rowsize, 8, ascii);
126 test_hexdump(len, rowsize, 1, ascii);
127}
128
114fc1af
AS
129static void __init test_hexdump_overflow(bool ascii)
130{
131 char buf[56];
132 const char *t = test_data_1_le[0];
133 size_t l = get_random_int() % sizeof(buf);
134 bool a;
135 int e, r;
136
137 memset(buf, ' ', sizeof(buf));
138
139 r = hex_dump_to_buffer(data_b, 1, 16, 1, buf, l, ascii);
140
141 if (ascii)
142 e = 50;
143 else
144 e = 2;
145 buf[e + 2] = '\0';
146
147 if (!l) {
148 a = r == e && buf[0] == ' ';
149 } else if (l < 3) {
150 a = r == e && buf[0] == '\0';
151 } else if (l < 4) {
152 a = r == e && !strcmp(buf, t);
153 } else if (ascii) {
154 if (l < 51)
155 a = r == e && buf[l - 1] == '\0' && buf[l - 2] == ' ';
156 else
157 a = r == e && buf[50] == '\0' && buf[49] == '.';
158 } else {
159 a = r == e && buf[e] == '\0';
160 }
161
162 if (!a) {
163 pr_err("Len: %zu rc: %u strlen: %zu\n", l, r, strlen(buf));
164 pr_err("Result: '%s'\n", buf);
165 }
166}
167
64d1d77a
AS
168static int __init test_hexdump_init(void)
169{
170 unsigned int i;
171 int rowsize;
172
173 pr_info("Running tests...\n");
174
175 rowsize = (get_random_int() % 2 + 1) * 16;
176 for (i = 0; i < 16; i++)
177 test_hexdump_set(rowsize, false);
178
179 rowsize = (get_random_int() % 2 + 1) * 16;
180 for (i = 0; i < 16; i++)
181 test_hexdump_set(rowsize, true);
182
114fc1af
AS
183 for (i = 0; i < 16; i++)
184 test_hexdump_overflow(false);
185
186 for (i = 0; i < 16; i++)
187 test_hexdump_overflow(true);
188
64d1d77a
AS
189 return -EINVAL;
190}
191module_init(test_hexdump_init);
192MODULE_LICENSE("Dual BSD/GPL");