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