chiark / gitweb /
tree-wide: drop license boilerplate
[elogind.git] / src / test / test-hexdecoct.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2 /***
3   This file is part of systemd.
4
5   Copyright 2010 Lennart Poettering
6 ***/
7
8 #include <errno.h>
9
10 #include "alloc-util.h"
11 #include "hexdecoct.h"
12 #include "macro.h"
13 #include "string-util.h"
14
15 /// Additional includes needed by elogind
16 #include "musl_missing.h"
17
18 static void test_hexchar(void) {
19         assert_se(hexchar(0xa) == 'a');
20         assert_se(hexchar(0x0) == '0');
21 }
22
23 static void test_unhexchar(void) {
24         assert_se(unhexchar('a') == 0xA);
25         assert_se(unhexchar('A') == 0xA);
26         assert_se(unhexchar('0') == 0x0);
27 }
28
29 static void test_base32hexchar(void) {
30         assert_se(base32hexchar(0) == '0');
31         assert_se(base32hexchar(9) == '9');
32         assert_se(base32hexchar(10) == 'A');
33         assert_se(base32hexchar(31) == 'V');
34 }
35
36 static void test_unbase32hexchar(void) {
37         assert_se(unbase32hexchar('0') == 0);
38         assert_se(unbase32hexchar('9') == 9);
39         assert_se(unbase32hexchar('A') == 10);
40         assert_se(unbase32hexchar('V') == 31);
41         assert_se(unbase32hexchar('=') == -EINVAL);
42 }
43
44 static void test_base64char(void) {
45         assert_se(base64char(0) == 'A');
46         assert_se(base64char(26) == 'a');
47         assert_se(base64char(63) == '/');
48 }
49
50 static void test_unbase64char(void) {
51         assert_se(unbase64char('A') == 0);
52         assert_se(unbase64char('Z') == 25);
53         assert_se(unbase64char('a') == 26);
54         assert_se(unbase64char('z') == 51);
55         assert_se(unbase64char('0') == 52);
56         assert_se(unbase64char('9') == 61);
57         assert_se(unbase64char('+') == 62);
58         assert_se(unbase64char('/') == 63);
59         assert_se(unbase64char('=') == -EINVAL);
60 }
61
62 static void test_octchar(void) {
63         assert_se(octchar(00) == '0');
64         assert_se(octchar(07) == '7');
65 }
66
67 static void test_unoctchar(void) {
68         assert_se(unoctchar('0') == 00);
69         assert_se(unoctchar('7') == 07);
70 }
71
72 static void test_decchar(void) {
73         assert_se(decchar(0) == '0');
74         assert_se(decchar(9) == '9');
75 }
76
77 static void test_undecchar(void) {
78         assert_se(undecchar('0') == 0);
79         assert_se(undecchar('9') == 9);
80 }
81
82 static void test_unhexmem(void) {
83         const char *hex = "efa2149213";
84         const char *hex_invalid = "efa214921o";
85         _cleanup_free_ char *hex2 = NULL;
86         _cleanup_free_ void *mem = NULL;
87         size_t len;
88
89         assert_se(unhexmem(hex_invalid, strlen(hex_invalid), &mem, &len) == -EINVAL);
90         assert_se(unhexmem(hex, strlen(hex) + 1, &mem, &len) == -EINVAL);
91         assert_se(unhexmem(hex, strlen(hex) - 1, &mem, &len) == -EINVAL);
92         assert_se(unhexmem(hex, strlen(hex), &mem, &len) == 0);
93
94         assert_se((hex2 = hexmem(mem, len)));
95         assert_se(streq(hex, hex2));
96 }
97
98 /* https://tools.ietf.org/html/rfc4648#section-10 */
99 static void test_base32hexmem(void) {
100         char *b32;
101
102         b32 = base32hexmem("", STRLEN(""), true);
103         assert_se(b32);
104         assert_se(streq(b32, ""));
105         free(b32);
106
107         b32 = base32hexmem("f", STRLEN("f"), true);
108         assert_se(b32);
109         assert_se(streq(b32, "CO======"));
110         free(b32);
111
112         b32 = base32hexmem("fo", STRLEN("fo"), true);
113         assert_se(b32);
114         assert_se(streq(b32, "CPNG===="));
115         free(b32);
116
117         b32 = base32hexmem("foo", STRLEN("foo"), true);
118         assert_se(b32);
119         assert_se(streq(b32, "CPNMU==="));
120         free(b32);
121
122         b32 = base32hexmem("foob", STRLEN("foob"), true);
123         assert_se(b32);
124         assert_se(streq(b32, "CPNMUOG="));
125         free(b32);
126
127         b32 = base32hexmem("fooba", STRLEN("fooba"), true);
128         assert_se(b32);
129         assert_se(streq(b32, "CPNMUOJ1"));
130         free(b32);
131
132         b32 = base32hexmem("foobar", STRLEN("foobar"), true);
133         assert_se(b32);
134         assert_se(streq(b32, "CPNMUOJ1E8======"));
135         free(b32);
136
137         b32 = base32hexmem("", STRLEN(""), false);
138         assert_se(b32);
139         assert_se(streq(b32, ""));
140         free(b32);
141
142         b32 = base32hexmem("f", STRLEN("f"), false);
143         assert_se(b32);
144         assert_se(streq(b32, "CO"));
145         free(b32);
146
147         b32 = base32hexmem("fo", STRLEN("fo"), false);
148         assert_se(b32);
149         assert_se(streq(b32, "CPNG"));
150         free(b32);
151
152         b32 = base32hexmem("foo", STRLEN("foo"), false);
153         assert_se(b32);
154         assert_se(streq(b32, "CPNMU"));
155         free(b32);
156
157         b32 = base32hexmem("foob", STRLEN("foob"), false);
158         assert_se(b32);
159         assert_se(streq(b32, "CPNMUOG"));
160         free(b32);
161
162         b32 = base32hexmem("fooba", STRLEN("fooba"), false);
163         assert_se(b32);
164         assert_se(streq(b32, "CPNMUOJ1"));
165         free(b32);
166
167         b32 = base32hexmem("foobar", STRLEN("foobar"), false);
168         assert_se(b32);
169         assert_se(streq(b32, "CPNMUOJ1E8"));
170         free(b32);
171 }
172
173 static void test_unbase32hexmem(void) {
174         void *mem;
175         size_t len;
176
177         assert_se(unbase32hexmem("", STRLEN(""), true, &mem, &len) == 0);
178         assert_se(streq(strndupa(mem, len), ""));
179         free(mem);
180
181         assert_se(unbase32hexmem("CO======", STRLEN("CO======"), true, &mem, &len) == 0);
182         assert_se(streq(strndupa(mem, len), "f"));
183         free(mem);
184
185         assert_se(unbase32hexmem("CPNG====", STRLEN("CPNG===="), true, &mem, &len) == 0);
186         assert_se(streq(strndupa(mem, len), "fo"));
187         free(mem);
188
189         assert_se(unbase32hexmem("CPNMU===", STRLEN("CPNMU==="), true, &mem, &len) == 0);
190         assert_se(streq(strndupa(mem, len), "foo"));
191         free(mem);
192
193         assert_se(unbase32hexmem("CPNMUOG=", STRLEN("CPNMUOG="), true, &mem, &len) == 0);
194         assert_se(streq(strndupa(mem, len), "foob"));
195         free(mem);
196
197         assert_se(unbase32hexmem("CPNMUOJ1", STRLEN("CPNMUOJ1"), true, &mem, &len) == 0);
198         assert_se(streq(strndupa(mem, len), "fooba"));
199         free(mem);
200
201         assert_se(unbase32hexmem("CPNMUOJ1E8======", STRLEN("CPNMUOJ1E8======"), true, &mem, &len) == 0);
202         assert_se(streq(strndupa(mem, len), "foobar"));
203         free(mem);
204
205         assert_se(unbase32hexmem("A", STRLEN("A"), true, &mem, &len) == -EINVAL);
206         assert_se(unbase32hexmem("A=======", STRLEN("A======="), true, &mem, &len) == -EINVAL);
207         assert_se(unbase32hexmem("AAA=====", STRLEN("AAA====="), true, &mem, &len) == -EINVAL);
208         assert_se(unbase32hexmem("AAAAAA==", STRLEN("AAAAAA=="), true, &mem, &len) == -EINVAL);
209         assert_se(unbase32hexmem("AB======", STRLEN("AB======"), true, &mem, &len) == -EINVAL);
210         assert_se(unbase32hexmem("AAAB====", STRLEN("AAAB===="), true, &mem, &len) == -EINVAL);
211         assert_se(unbase32hexmem("AAAAB===", STRLEN("AAAAB==="), true, &mem, &len) == -EINVAL);
212         assert_se(unbase32hexmem("AAAAAAB=", STRLEN("AAAAAAB="), true, &mem, &len) == -EINVAL);
213
214         assert_se(unbase32hexmem("XPNMUOJ1", STRLEN("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
215         assert_se(unbase32hexmem("CXNMUOJ1", STRLEN("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
216         assert_se(unbase32hexmem("CPXMUOJ1", STRLEN("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
217         assert_se(unbase32hexmem("CPNXUOJ1", STRLEN("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
218         assert_se(unbase32hexmem("CPNMXOJ1", STRLEN("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
219         assert_se(unbase32hexmem("CPNMUXJ1", STRLEN("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
220         assert_se(unbase32hexmem("CPNMUOX1", STRLEN("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
221         assert_se(unbase32hexmem("CPNMUOJX", STRLEN("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
222
223         assert_se(unbase32hexmem("", STRLEN(""), false, &mem, &len) == 0);
224         assert_se(streq(strndupa(mem, len), ""));
225         free(mem);
226
227         assert_se(unbase32hexmem("CO", STRLEN("CO"), false, &mem, &len) == 0);
228         assert_se(streq(strndupa(mem, len), "f"));
229         free(mem);
230
231         assert_se(unbase32hexmem("CPNG", STRLEN("CPNG"), false, &mem, &len) == 0);
232         assert_se(streq(strndupa(mem, len), "fo"));
233         free(mem);
234
235         assert_se(unbase32hexmem("CPNMU", STRLEN("CPNMU"), false, &mem, &len) == 0);
236         assert_se(streq(strndupa(mem, len), "foo"));
237         free(mem);
238
239         assert_se(unbase32hexmem("CPNMUOG", STRLEN("CPNMUOG"), false, &mem, &len) == 0);
240         assert_se(streq(strndupa(mem, len), "foob"));
241         free(mem);
242
243         assert_se(unbase32hexmem("CPNMUOJ1", STRLEN("CPNMUOJ1"), false, &mem, &len) == 0);
244         assert_se(streq(strndupa(mem, len), "fooba"));
245         free(mem);
246
247         assert_se(unbase32hexmem("CPNMUOJ1E8", STRLEN("CPNMUOJ1E8"), false, &mem, &len) == 0);
248         assert_se(streq(strndupa(mem, len), "foobar"));
249         free(mem);
250
251         assert_se(unbase32hexmem("CPNMUOG=", STRLEN("CPNMUOG="), false, &mem, &len) == -EINVAL);
252         assert_se(unbase32hexmem("CPNMUOJ1E8======", STRLEN("CPNMUOJ1E8======"), false, &mem, &len) == -EINVAL);
253         assert_se(unbase32hexmem("A", STRLEN("A"), false, &mem, &len) == -EINVAL);
254         assert_se(unbase32hexmem("A", STRLEN("A"), false, &mem, &len) == -EINVAL);
255         assert_se(unbase32hexmem("AAA", STRLEN("AAA"), false, &mem, &len) == -EINVAL);
256         assert_se(unbase32hexmem("AAAAAA", STRLEN("AAAAAA"), false, &mem, &len) == -EINVAL);
257         assert_se(unbase32hexmem("AB", STRLEN("AB"), false, &mem, &len) == -EINVAL);
258         assert_se(unbase32hexmem("AAAB", STRLEN("AAAB"), false, &mem, &len) == -EINVAL);
259         assert_se(unbase32hexmem("AAAAB", STRLEN("AAAAB"), false, &mem, &len) == -EINVAL);
260         assert_se(unbase32hexmem("AAAAAAB", STRLEN("AAAAAAB"), false, &mem, &len) == -EINVAL);
261 }
262
263 /* https://tools.ietf.org/html/rfc4648#section-10 */
264 static void test_base64mem(void) {
265         char *b64;
266
267         assert_se(base64mem("", STRLEN(""), &b64) == 0);
268         assert_se(streq(b64, ""));
269         free(b64);
270
271         assert_se(base64mem("f", STRLEN("f"), &b64) == 4);
272         assert_se(streq(b64, "Zg=="));
273         free(b64);
274
275         assert_se(base64mem("fo", STRLEN("fo"), &b64) == 4);
276         assert_se(streq(b64, "Zm8="));
277         free(b64);
278
279         assert_se(base64mem("foo", STRLEN("foo"), &b64) == 4);
280         assert_se(streq(b64, "Zm9v"));
281         free(b64);
282
283         assert_se(base64mem("foob", STRLEN("foob"), &b64) == 8);
284         assert_se(streq(b64, "Zm9vYg=="));
285         free(b64);
286
287         assert_se(base64mem("fooba", STRLEN("fooba"), &b64) == 8);
288         assert_se(streq(b64, "Zm9vYmE="));
289         free(b64);
290
291         assert_se(base64mem("foobar", STRLEN("foobar"), &b64) == 8);
292         assert_se(streq(b64, "Zm9vYmFy"));
293         free(b64);
294 }
295
296 static void test_unbase64mem_one(const char *input, const char *output, int ret) {
297         _cleanup_free_ void *buffer = NULL;
298         size_t size = 0;
299
300         assert_se(unbase64mem(input, (size_t) -1, &buffer, &size) == ret);
301
302         if (ret >= 0) {
303                 assert_se(size == strlen(output));
304                 assert_se(memcmp(buffer, output, size) == 0);
305                 assert_se(((char*) buffer)[size] == 0);
306         }
307 }
308
309 static void test_unbase64mem(void) {
310
311         test_unbase64mem_one("", "", 0);
312         test_unbase64mem_one("Zg==", "f", 0);
313         test_unbase64mem_one("Zm8=", "fo", 0);
314         test_unbase64mem_one("Zm9v", "foo", 0);
315         test_unbase64mem_one("Zm9vYg==", "foob", 0);
316         test_unbase64mem_one("Zm9vYmE=", "fooba", 0);
317         test_unbase64mem_one("Zm9vYmFy", "foobar", 0);
318
319         test_unbase64mem_one(" ", "", 0);
320         test_unbase64mem_one(" \n\r ", "", 0);
321         test_unbase64mem_one("    Zg\n==       ", "f", 0);
322         test_unbase64mem_one(" Zm 8=\r", "fo", 0);
323         test_unbase64mem_one("  Zm9\n\r\r\nv   ", "foo", 0);
324         test_unbase64mem_one(" Z m9vYg==\n\r", "foob", 0);
325         test_unbase64mem_one(" Zm 9vYmE=   ", "fooba", 0);
326         test_unbase64mem_one("   Z m9v    YmFy   ", "foobar", 0);
327
328         test_unbase64mem_one("A", NULL, -EPIPE);
329         test_unbase64mem_one("A====", NULL, -EINVAL);
330         test_unbase64mem_one("AAB==", NULL, -EINVAL);
331         test_unbase64mem_one(" A A A B = ", NULL, -EINVAL);
332         test_unbase64mem_one(" Z m 8 = q u u x ", NULL, -ENAMETOOLONG);
333 }
334
335 static void test_hexdump(void) {
336         uint8_t data[146];
337         unsigned i;
338
339         hexdump(stdout, NULL, 0);
340         hexdump(stdout, "", 0);
341         hexdump(stdout, "", 1);
342         hexdump(stdout, "x", 1);
343         hexdump(stdout, "x", 2);
344         hexdump(stdout, "foobar", 7);
345         hexdump(stdout, "f\nobar", 7);
346         hexdump(stdout, "xxxxxxxxxxxxxxxxxxxxyz", 23);
347
348         for (i = 0; i < ELEMENTSOF(data); i++)
349                 data[i] = i*2;
350
351         hexdump(stdout, data, sizeof(data));
352 }
353
354 int main(int argc, char *argv[]) {
355         test_hexchar();
356         test_unhexchar();
357         test_base32hexchar();
358         test_unbase32hexchar();
359         test_base64char();
360         test_unbase64char();
361         test_octchar();
362         test_unoctchar();
363         test_decchar();
364         test_undecchar();
365         test_unhexmem();
366         test_base32hexmem();
367         test_unbase32hexmem();
368         test_base64mem();
369         test_unbase64mem();
370         test_hexdump();
371
372         return 0;
373 }