test_hexdump: define FILL_CHAR constant
[linux-2.6-block.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
3db4a987
AS
45#define FILL_CHAR '#'
46
87977ca6
AS
47static void __init test_hexdump_prepare_test(size_t len, int rowsize,
48 int groupsize, char *test,
49 size_t testlen, bool ascii)
64d1d77a 50{
64d1d77a 51 char *p;
17974c05 52 const char * const *result;
64d1d77a
AS
53 size_t l = len;
54 int gs = groupsize, rs = rowsize;
55 unsigned int i;
56
64d1d77a
AS
57 if (rs != 16 && rs != 32)
58 rs = 16;
59
60 if (l > rs)
61 l = rs;
62
63 if (!is_power_of_2(gs) || gs > 8 || (len % gs != 0))
64 gs = 1;
65
66 if (gs == 8)
67 result = test_data_8_le;
68 else if (gs == 4)
69 result = test_data_4_le;
70 else if (gs == 2)
71 result = test_data_2_le;
72 else
73 result = test_data_1_le;
74
3db4a987 75 memset(test, FILL_CHAR, testlen);
64d1d77a
AS
76
77 /* hex dump */
78 p = test;
79 for (i = 0; i < l / gs; i++) {
80 const char *q = *result++;
81 size_t amount = strlen(q);
82
83 strncpy(p, q, amount);
3db4a987
AS
84 p += amount;
85
86 *p++ = ' ';
64d1d77a
AS
87 }
88 if (i)
89 p--;
90
91 /* ASCII part */
92 if (ascii) {
3db4a987
AS
93 do {
94 *p++ = ' ';
95 } while (p < test + rs * 2 + rs / gs + 1);
96
64d1d77a
AS
97 strncpy(p, data_a, l);
98 p += l;
99 }
100
101 *p = '\0';
87977ca6
AS
102}
103
104#define TEST_HEXDUMP_BUF_SIZE (32 * 3 + 2 + 32 + 1)
105
106static void __init test_hexdump(size_t len, int rowsize, int groupsize,
107 bool ascii)
108{
109 char test[TEST_HEXDUMP_BUF_SIZE];
110 char real[TEST_HEXDUMP_BUF_SIZE];
111
112 hex_dump_to_buffer(data_b, len, rowsize, groupsize, real, sizeof(real),
113 ascii);
114
115 test_hexdump_prepare_test(len, rowsize, groupsize, test, sizeof(test),
116 ascii);
64d1d77a
AS
117
118 if (strcmp(test, real)) {
119 pr_err("Len: %zu row: %d group: %d\n", len, rowsize, groupsize);
120 pr_err("Result: '%s'\n", real);
121 pr_err("Expect: '%s'\n", test);
122 }
123}
124
125static void __init test_hexdump_set(int rowsize, bool ascii)
126{
127 size_t d = min_t(size_t, sizeof(data_b), rowsize);
128 size_t len = get_random_int() % d + 1;
129
130 test_hexdump(len, rowsize, 4, ascii);
131 test_hexdump(len, rowsize, 2, ascii);
132 test_hexdump(len, rowsize, 8, ascii);
133 test_hexdump(len, rowsize, 1, ascii);
134}
135
114fc1af
AS
136static void __init test_hexdump_overflow(bool ascii)
137{
138 char buf[56];
139 const char *t = test_data_1_le[0];
140 size_t l = get_random_int() % sizeof(buf);
141 bool a;
142 int e, r;
143
3db4a987 144 memset(buf, FILL_CHAR, sizeof(buf));
114fc1af
AS
145
146 r = hex_dump_to_buffer(data_b, 1, 16, 1, buf, l, ascii);
147
148 if (ascii)
149 e = 50;
150 else
151 e = 2;
152 buf[e + 2] = '\0';
153
154 if (!l) {
3db4a987 155 a = r == e && buf[0] == FILL_CHAR;
114fc1af
AS
156 } else if (l < 3) {
157 a = r == e && buf[0] == '\0';
158 } else if (l < 4) {
159 a = r == e && !strcmp(buf, t);
160 } else if (ascii) {
161 if (l < 51)
3db4a987 162 a = r == e && buf[l - 1] == '\0' && buf[l - 2] == FILL_CHAR;
114fc1af
AS
163 else
164 a = r == e && buf[50] == '\0' && buf[49] == '.';
165 } else {
166 a = r == e && buf[e] == '\0';
167 }
168
169 if (!a) {
170 pr_err("Len: %zu rc: %u strlen: %zu\n", l, r, strlen(buf));
171 pr_err("Result: '%s'\n", buf);
172 }
173}
174
64d1d77a
AS
175static int __init test_hexdump_init(void)
176{
177 unsigned int i;
178 int rowsize;
179
180 pr_info("Running tests...\n");
181
182 rowsize = (get_random_int() % 2 + 1) * 16;
183 for (i = 0; i < 16; i++)
184 test_hexdump_set(rowsize, false);
185
186 rowsize = (get_random_int() % 2 + 1) * 16;
187 for (i = 0; i < 16; i++)
188 test_hexdump_set(rowsize, true);
189
114fc1af
AS
190 for (i = 0; i < 16; i++)
191 test_hexdump_overflow(false);
192
193 for (i = 0; i < 16; i++)
194 test_hexdump_overflow(true);
195
64d1d77a
AS
196 return -EINVAL;
197}
198module_init(test_hexdump_init);
199MODULE_LICENSE("Dual BSD/GPL");