]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/test/test-util.c
util: split out escaping code into escape.[ch]
[thirdparty/systemd.git] / src / test / test-util.c
CommitLineData
539ad707
TA
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2010 Lennart Poettering
7 Copyright 2013 Thomas H.P. Andersen
8
9 systemd is free software; you can redistribute it and/or modify it
10 under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation; either version 2.1 of the License, or
12 (at your option) any later version.
13
14 systemd is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
18
19 You should have received a copy of the GNU Lesser General Public License
20 along with systemd; If not, see <http://www.gnu.org/licenses/>.
21***/
22
618234a5 23#include <errno.h>
dbd73f9e 24#include <fcntl.h>
d6dd604b 25#include <locale.h>
8e211000 26#include <math.h>
618234a5
LP
27#include <signal.h>
28#include <string.h>
df241a67 29#include <sys/types.h>
8852362b 30#include <sys/wait.h>
df241a67 31#include <sys/xattr.h>
618234a5 32#include <unistd.h>
539ad707 33
618234a5
LP
34#include "conf-parser.h"
35#include "cpu-set-util.h"
65b3903f 36#include "def.h"
4f5dd394 37#include "escape.h"
65b3903f 38#include "fileio.h"
618234a5 39#include "mkdir.h"
0b452006 40#include "process-util.h"
618234a5 41#include "rm-rf.h"
24882e06 42#include "signal-util.h"
618234a5
LP
43#include "strv.h"
44#include "util.h"
45#include "virt.h"
539ad707
TA
46
47static void test_streq_ptr(void) {
8354c34e
TA
48 assert_se(streq_ptr(NULL, NULL));
49 assert_se(!streq_ptr("abc", "cdef"));
539ad707
TA
50}
51
625e870b
DH
52static void test_align_power2(void) {
53 unsigned long i, p2;
54
55 assert_se(ALIGN_POWER2(0) == 0);
56 assert_se(ALIGN_POWER2(1) == 1);
57 assert_se(ALIGN_POWER2(2) == 2);
58 assert_se(ALIGN_POWER2(3) == 4);
59 assert_se(ALIGN_POWER2(12) == 16);
60
61 assert_se(ALIGN_POWER2(ULONG_MAX) == 0);
62 assert_se(ALIGN_POWER2(ULONG_MAX - 1) == 0);
63 assert_se(ALIGN_POWER2(ULONG_MAX - 1024) == 0);
64 assert_se(ALIGN_POWER2(ULONG_MAX / 2) == ULONG_MAX / 2 + 1);
65 assert_se(ALIGN_POWER2(ULONG_MAX + 1) == 0);
66
67 for (i = 1; i < 131071; ++i) {
68 for (p2 = 1; p2 < i; p2 <<= 1)
69 /* empty */ ;
70
71 assert_se(ALIGN_POWER2(i) == p2);
72 }
73
74 for (i = ULONG_MAX - 1024; i < ULONG_MAX; ++i) {
75 for (p2 = 1; p2 && p2 < i; p2 <<= 1)
76 /* empty */ ;
77
78 assert_se(ALIGN_POWER2(i) == p2);
79 }
80}
81
7242d742
DH
82static void test_max(void) {
83 static const struct {
84 int a;
85 int b[CONST_MAX(10, 100)];
86 } val1 = {
87 .a = CONST_MAX(10, 100),
88 };
89 int d = 0;
90
91 assert_cc(sizeof(val1.b) == sizeof(int) * 100);
92
93 /* CONST_MAX returns (void) instead of a value if the passed arguments
94 * are not of the same type or not constant expressions. */
95 assert_cc(__builtin_types_compatible_p(typeof(CONST_MAX(1, 10)), int));
7242d742
DH
96 assert_cc(__builtin_types_compatible_p(typeof(CONST_MAX(1, 1U)), void));
97
98 assert_se(val1.a == 100);
99 assert_se(MAX(++d, 0) == 1);
100 assert_se(d == 1);
40a1eebd
DH
101
102 assert_cc(MAXSIZE(char[3], uint16_t) == 3);
103 assert_cc(MAXSIZE(char[3], uint32_t) == 4);
104 assert_cc(MAXSIZE(char, long) == sizeof(long));
667a0377
DH
105
106 assert_se(MAX(-5, 5) == 5);
107 assert_se(MAX(5, 5) == 5);
108 assert_se(MAX(MAX(1, MAX(2, MAX(3, 4))), 5) == 5);
109 assert_se(MAX(MAX(1, MAX(2, MAX(3, 2))), 1) == 3);
110 assert_se(MAX(MIN(1, MIN(2, MIN(3, 4))), 5) == 5);
111 assert_se(MAX(MAX(1, MIN(2, MIN(3, 2))), 1) == 2);
112 assert_se(LESS_BY(8, 4) == 4);
113 assert_se(LESS_BY(8, 8) == 0);
114 assert_se(LESS_BY(4, 8) == 0);
115 assert_se(LESS_BY(16, LESS_BY(8, 4)) == 12);
116 assert_se(LESS_BY(4, LESS_BY(8, 4)) == 0);
117 assert_se(CLAMP(-5, 0, 1) == 0);
118 assert_se(CLAMP(5, 0, 1) == 1);
119 assert_se(CLAMP(5, -10, 1) == 1);
120 assert_se(CLAMP(5, -10, 10) == 5);
121 assert_se(CLAMP(CLAMP(0, -10, 10), CLAMP(-5, 10, 20), CLAMP(100, -5, 20)) == 10);
7242d742
DH
122}
123
fb835651
DH
124static void test_container_of(void) {
125 struct mytype {
126 uint8_t pad1[3];
127 uint64_t v1;
128 uint8_t pad2[2];
129 uint32_t v2;
130 } _packed_ myval = { };
131
132 assert_cc(sizeof(myval) == 17);
133 assert_se(container_of(&myval.v1, struct mytype, v1) == &myval);
134 assert_se(container_of(&myval.v2, struct mytype, v2) == &myval);
135 assert_se(container_of(&container_of(&myval.v2,
136 struct mytype,
137 v2)->v1,
138 struct mytype,
139 v1) == &myval);
140}
141
95d78c7e
DH
142static void test_alloca(void) {
143 static const uint8_t zero[997] = { };
144 char *t;
145
146 t = alloca_align(17, 512);
147 assert_se(!((uintptr_t)t & 0xff));
148 memzero(t, 17);
149
150 t = alloca0_align(997, 1024);
151 assert_se(!((uintptr_t)t & 0x1ff));
152 assert_se(!memcmp(t, zero, 997));
153}
154
180a60bc
DH
155static void test_div_round_up(void) {
156 int div;
157
158 /* basic tests */
159 assert_se(DIV_ROUND_UP(0, 8) == 0);
160 assert_se(DIV_ROUND_UP(1, 8) == 1);
161 assert_se(DIV_ROUND_UP(8, 8) == 1);
162 assert_se(DIV_ROUND_UP(12, 8) == 2);
163 assert_se(DIV_ROUND_UP(16, 8) == 2);
164
165 /* test multiple evaluation */
166 div = 0;
167 assert_se(DIV_ROUND_UP(div++, 8) == 0 && div == 1);
168 assert_se(DIV_ROUND_UP(++div, 8) == 1 && div == 2);
169 assert_se(DIV_ROUND_UP(8, div++) == 4 && div == 3);
170 assert_se(DIV_ROUND_UP(8, ++div) == 2 && div == 4);
171
172 /* overflow test with exact division */
173 assert_se(sizeof(0U) == 4);
174 assert_se(0xfffffffaU % 10U == 0U);
175 assert_se(0xfffffffaU / 10U == 429496729U);
176 assert_se(DIV_ROUND_UP(0xfffffffaU, 10U) == 429496729U);
177 assert_se((0xfffffffaU + 10U - 1U) / 10U == 0U);
178 assert_se(0xfffffffaU / 10U + !!(0xfffffffaU % 10U) == 429496729U);
179
180 /* overflow test with rounded division */
181 assert_se(0xfffffffdU % 10U == 3U);
182 assert_se(0xfffffffdU / 10U == 429496729U);
183 assert_se(DIV_ROUND_UP(0xfffffffdU, 10U) == 429496730U);
184 assert_se((0xfffffffdU + 10U - 1U) / 10U == 0U);
185 assert_se(0xfffffffdU / 10U + !!(0xfffffffdU % 10U) == 429496730U);
186}
187
539ad707 188static void test_first_word(void) {
8354c34e
TA
189 assert_se(first_word("Hello", ""));
190 assert_se(first_word("Hello", "Hello"));
191 assert_se(first_word("Hello world", "Hello"));
192 assert_se(first_word("Hello\tworld", "Hello"));
193 assert_se(first_word("Hello\nworld", "Hello"));
194 assert_se(first_word("Hello\rworld", "Hello"));
195 assert_se(first_word("Hello ", "Hello"));
196
197 assert_se(!first_word("Hello", "Hellooo"));
198 assert_se(!first_word("Hello", "xxxxx"));
199 assert_se(!first_word("Hellooo", "Hello"));
200}
201
dbd73f9e
TA
202static void test_close_many(void) {
203 int fds[3];
204 char name0[] = "/tmp/test-close-many.XXXXXX";
205 char name1[] = "/tmp/test-close-many.XXXXXX";
206 char name2[] = "/tmp/test-close-many.XXXXXX";
207
2d5bdf5b
LP
208 fds[0] = mkostemp_safe(name0, O_RDWR|O_CLOEXEC);
209 fds[1] = mkostemp_safe(name1, O_RDWR|O_CLOEXEC);
210 fds[2] = mkostemp_safe(name2, O_RDWR|O_CLOEXEC);
dbd73f9e
TA
211
212 close_many(fds, 2);
213
214 assert_se(fcntl(fds[0], F_GETFD) == -1);
215 assert_se(fcntl(fds[1], F_GETFD) == -1);
216 assert_se(fcntl(fds[2], F_GETFD) >= 0);
217
03e334a1 218 safe_close(fds[2]);
dbd73f9e
TA
219
220 unlink(name0);
221 unlink(name1);
222 unlink(name2);
223}
224
8354c34e
TA
225static void test_parse_boolean(void) {
226 assert_se(parse_boolean("1") == 1);
227 assert_se(parse_boolean("y") == 1);
228 assert_se(parse_boolean("Y") == 1);
229 assert_se(parse_boolean("yes") == 1);
230 assert_se(parse_boolean("YES") == 1);
231 assert_se(parse_boolean("true") == 1);
232 assert_se(parse_boolean("TRUE") == 1);
233 assert_se(parse_boolean("on") == 1);
234 assert_se(parse_boolean("ON") == 1);
235
236 assert_se(parse_boolean("0") == 0);
237 assert_se(parse_boolean("n") == 0);
238 assert_se(parse_boolean("N") == 0);
239 assert_se(parse_boolean("no") == 0);
240 assert_se(parse_boolean("NO") == 0);
241 assert_se(parse_boolean("false") == 0);
242 assert_se(parse_boolean("FALSE") == 0);
243 assert_se(parse_boolean("off") == 0);
244 assert_se(parse_boolean("OFF") == 0);
245
246 assert_se(parse_boolean("garbage") < 0);
247 assert_se(parse_boolean("") < 0);
0f625d0b 248 assert_se(parse_boolean("full") < 0);
539ad707
TA
249}
250
8d99e5f5
TA
251static void test_parse_pid(void) {
252 int r;
253 pid_t pid;
254
255 r = parse_pid("100", &pid);
256 assert_se(r == 0);
257 assert_se(pid == 100);
258
259 r = parse_pid("0x7FFFFFFF", &pid);
260 assert_se(r == 0);
261 assert_se(pid == 2147483647);
262
263 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
264 r = parse_pid("0", &pid);
265 assert_se(r == -ERANGE);
266 assert_se(pid == 65);
267
268 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
269 r = parse_pid("-100", &pid);
270 assert_se(r == -ERANGE);
271 assert_se(pid == 65);
272
273 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
274 r = parse_pid("0xFFFFFFFFFFFFFFFFF", &pid);
bdf7026e 275 assert_se(r == -ERANGE);
8d99e5f5 276 assert_se(pid == 65);
348637b2
LP
277
278 r = parse_pid("junk", &pid);
279 assert_se(r == -EINVAL);
8d99e5f5
TA
280}
281
282static void test_parse_uid(void) {
283 int r;
284 uid_t uid;
285
286 r = parse_uid("100", &uid);
287 assert_se(r == 0);
288 assert_se(uid == 100);
ff9265d0
DM
289
290 r = parse_uid("65535", &uid);
291 assert_se(r == -ENXIO);
ef5c570e
LP
292
293 r = parse_uid("asdsdas", &uid);
294 assert_se(r == -EINVAL);
ff9265d0
DM
295}
296
297static void test_safe_atou16(void) {
298 int r;
299 uint16_t l;
300
301 r = safe_atou16("12345", &l);
302 assert_se(r == 0);
303 assert_se(l == 12345);
304
305 r = safe_atou16("123456", &l);
306 assert_se(r == -ERANGE);
307
308 r = safe_atou16("junk", &l);
309 assert_se(r == -EINVAL);
310}
311
312static void test_safe_atoi16(void) {
313 int r;
314 int16_t l;
315
316 r = safe_atoi16("-12345", &l);
317 assert_se(r == 0);
318 assert_se(l == -12345);
319
320 r = safe_atoi16("36536", &l);
321 assert_se(r == -ERANGE);
322
323 r = safe_atoi16("junk", &l);
324 assert_se(r == -EINVAL);
8d99e5f5
TA
325}
326
327static void test_safe_atolli(void) {
328 int r;
329 long long l;
330
331 r = safe_atolli("12345", &l);
332 assert_se(r == 0);
333 assert_se(l == 12345);
334
335 r = safe_atolli("junk", &l);
336 assert_se(r == -EINVAL);
337}
338
339static void test_safe_atod(void) {
340 int r;
341 double d;
d6dd604b
LP
342 char *e;
343
344 r = safe_atod("junk", &d);
345 assert_se(r == -EINVAL);
8d99e5f5
TA
346
347 r = safe_atod("0.2244", &d);
348 assert_se(r == 0);
8e211000 349 assert_se(fabs(d - 0.2244) < 0.000001);
8d99e5f5 350
d6dd604b 351 r = safe_atod("0,5", &d);
8d99e5f5 352 assert_se(r == -EINVAL);
d6dd604b
LP
353
354 errno = 0;
355 strtod("0,5", &e);
356 assert_se(*e == ',');
357
358 /* Check if this really is locale independent */
926446f4 359 if (setlocale(LC_NUMERIC, "de_DE.utf8")) {
d6dd604b 360
926446f4
DH
361 r = safe_atod("0.2244", &d);
362 assert_se(r == 0);
363 assert_se(fabs(d - 0.2244) < 0.000001);
d6dd604b 364
926446f4
DH
365 r = safe_atod("0,5", &d);
366 assert_se(r == -EINVAL);
d6dd604b 367
926446f4
DH
368 errno = 0;
369 assert_se(fabs(strtod("0,5", &e) - 0.5) < 0.00001);
370 }
d6dd604b
LP
371
372 /* And check again, reset */
926446f4 373 assert_se(setlocale(LC_NUMERIC, "C"));
d6dd604b
LP
374
375 r = safe_atod("0.2244", &d);
376 assert_se(r == 0);
8e211000 377 assert_se(fabs(d - 0.2244) < 0.000001);
d6dd604b
LP
378
379 r = safe_atod("0,5", &d);
380 assert_se(r == -EINVAL);
381
382 errno = 0;
383 strtod("0,5", &e);
384 assert_se(*e == ',');
8d99e5f5
TA
385}
386
dbd73f9e 387static void test_strappend(void) {
998b087f 388 _cleanup_free_ char *t1, *t2, *t3, *t4;
dbd73f9e 389
998b087f
TA
390 t1 = strappend(NULL, NULL);
391 assert_se(streq(t1, ""));
dbd73f9e 392
998b087f
TA
393 t2 = strappend(NULL, "suf");
394 assert_se(streq(t2, "suf"));
dbd73f9e 395
998b087f
TA
396 t3 = strappend("pre", NULL);
397 assert_se(streq(t3, "pre"));
dbd73f9e 398
998b087f
TA
399 t4 = strappend("pre", "suf");
400 assert_se(streq(t4, "presuf"));
dbd73f9e
TA
401}
402
1ef04f0b 403static void test_strstrip(void) {
998b087f
TA
404 char *r;
405 char input[] = " hello, waldo. ";
1ef04f0b 406
998b087f
TA
407 r = strstrip(input);
408 assert_se(streq(r, "hello, waldo."));
1ef04f0b
TA
409}
410
411static void test_delete_chars(void) {
998b087f
TA
412 char *r;
413 char input[] = " hello, waldo. abc";
1ef04f0b 414
998b087f
TA
415 r = delete_chars(input, WHITESPACE);
416 assert_se(streq(r, "hello,waldo.abc"));
1ef04f0b
TA
417}
418
419static void test_in_charset(void) {
998b087f
TA
420 assert_se(in_charset("dddaaabbbcccc", "abcd"));
421 assert_se(!in_charset("dddaaabbbcccc", "abc f"));
1ef04f0b
TA
422}
423
44f4c86c
DB
424static void test_hexchar(void) {
425 assert_se(hexchar(0xa) == 'a');
426 assert_se(hexchar(0x0) == '0');
427}
428
429static void test_unhexchar(void) {
430 assert_se(unhexchar('a') == 0xA);
431 assert_se(unhexchar('A') == 0xA);
432 assert_se(unhexchar('0') == 0x0);
433}
434
919a7f5f
TG
435static void test_base32hexchar(void) {
436 assert_se(base32hexchar(0) == '0');
437 assert_se(base32hexchar(9) == '9');
438 assert_se(base32hexchar(10) == 'A');
439 assert_se(base32hexchar(31) == 'V');
440}
441
442static void test_unbase32hexchar(void) {
443 assert_se(unbase32hexchar('0') == 0);
444 assert_se(unbase32hexchar('9') == 9);
445 assert_se(unbase32hexchar('A') == 10);
446 assert_se(unbase32hexchar('V') == 31);
447 assert_se(unbase32hexchar('=') == -EINVAL);
448}
449
13a5d76b
TG
450static void test_base64char(void) {
451 assert_se(base64char(0) == 'A');
452 assert_se(base64char(26) == 'a');
453 assert_se(base64char(63) == '/');
454}
455
456static void test_unbase64char(void) {
457 assert_se(unbase64char('A') == 0);
458 assert_se(unbase64char('Z') == 25);
459 assert_se(unbase64char('a') == 26);
460 assert_se(unbase64char('z') == 51);
461 assert_se(unbase64char('0') == 52);
462 assert_se(unbase64char('9') == 61);
463 assert_se(unbase64char('+') == 62);
464 assert_se(unbase64char('/') == 63);
465 assert_se(unbase64char('=') == -EINVAL);
466}
467
44f4c86c
DB
468static void test_octchar(void) {
469 assert_se(octchar(00) == '0');
470 assert_se(octchar(07) == '7');
471}
472
473static void test_unoctchar(void) {
474 assert_se(unoctchar('0') == 00);
475 assert_se(unoctchar('7') == 07);
476}
477
478static void test_decchar(void) {
479 assert_se(decchar(0) == '0');
480 assert_se(decchar(9) == '9');
481}
482
483static void test_undecchar(void) {
484 assert_se(undecchar('0') == 0);
485 assert_se(undecchar('9') == 9);
486}
487
30494563
TG
488static void test_unhexmem(void) {
489 const char *hex = "efa214921";
490 const char *hex_invalid = "efa214921o";
491 _cleanup_free_ char *hex2 = NULL;
492 _cleanup_free_ void *mem = NULL;
493 size_t len;
494
495 assert_se(unhexmem(hex, strlen(hex), &mem, &len) == 0);
496 assert_se(unhexmem(hex, strlen(hex) + 1, &mem, &len) == -EINVAL);
497 assert_se(unhexmem(hex_invalid, strlen(hex_invalid), &mem, &len) == -EINVAL);
498
499 assert_se((hex2 = hexmem(mem, len)));
500
501 free(mem);
502
503 assert_se(memcmp(hex, hex2, strlen(hex)) == 0);
504
505 free(hex2);
506
507 assert_se(unhexmem(hex, strlen(hex) - 1, &mem, &len) == 0);
508 assert_se((hex2 = hexmem(mem, len)));
509 assert_se(memcmp(hex, hex2, strlen(hex) - 1) == 0);
510}
511
919a7f5f
TG
512/* https://tools.ietf.org/html/rfc4648#section-10 */
513static void test_base32hexmem(void) {
514 char *b32;
515
516 b32 = base32hexmem("", strlen(""), true);
517 assert_se(b32);
518 assert_se(streq(b32, ""));
519 free(b32);
520
521 b32 = base32hexmem("f", strlen("f"), true);
522 assert_se(b32);
523 assert_se(streq(b32, "CO======"));
524 free(b32);
525
526 b32 = base32hexmem("fo", strlen("fo"), true);
527 assert_se(b32);
528 assert_se(streq(b32, "CPNG===="));
529 free(b32);
530
531 b32 = base32hexmem("foo", strlen("foo"), true);
532 assert_se(b32);
533 assert_se(streq(b32, "CPNMU==="));
534 free(b32);
535
536 b32 = base32hexmem("foob", strlen("foob"), true);
537 assert_se(b32);
538 assert_se(streq(b32, "CPNMUOG="));
539 free(b32);
540
541 b32 = base32hexmem("fooba", strlen("fooba"), true);
542 assert_se(b32);
543 assert_se(streq(b32, "CPNMUOJ1"));
544 free(b32);
545
546 b32 = base32hexmem("foobar", strlen("foobar"), true);
547 assert_se(b32);
548 assert_se(streq(b32, "CPNMUOJ1E8======"));
549 free(b32);
550
551 b32 = base32hexmem("", strlen(""), false);
552 assert_se(b32);
553 assert_se(streq(b32, ""));
554 free(b32);
555
556 b32 = base32hexmem("f", strlen("f"), false);
557 assert_se(b32);
558 assert_se(streq(b32, "CO"));
559 free(b32);
560
561 b32 = base32hexmem("fo", strlen("fo"), false);
562 assert_se(b32);
563 assert_se(streq(b32, "CPNG"));
564 free(b32);
565
566 b32 = base32hexmem("foo", strlen("foo"), false);
567 assert_se(b32);
568 assert_se(streq(b32, "CPNMU"));
569 free(b32);
570
571 b32 = base32hexmem("foob", strlen("foob"), false);
572 assert_se(b32);
573 assert_se(streq(b32, "CPNMUOG"));
574 free(b32);
575
576 b32 = base32hexmem("fooba", strlen("fooba"), false);
577 assert_se(b32);
578 assert_se(streq(b32, "CPNMUOJ1"));
579 free(b32);
580
581 b32 = base32hexmem("foobar", strlen("foobar"), false);
582 assert_se(b32);
583 assert_se(streq(b32, "CPNMUOJ1E8"));
584 free(b32);
585}
586
587static void test_unbase32hexmem(void) {
588 void *mem;
589 size_t len;
590
591 assert_se(unbase32hexmem("", strlen(""), true, &mem, &len) == 0);
592 assert_se(streq(strndupa(mem, len), ""));
593 free(mem);
594
595 assert_se(unbase32hexmem("CO======", strlen("CO======"), true, &mem, &len) == 0);
596 assert_se(streq(strndupa(mem, len), "f"));
597 free(mem);
598
599 assert_se(unbase32hexmem("CPNG====", strlen("CPNG===="), true, &mem, &len) == 0);
600 assert_se(streq(strndupa(mem, len), "fo"));
601 free(mem);
602
603 assert_se(unbase32hexmem("CPNMU===", strlen("CPNMU==="), true, &mem, &len) == 0);
604 assert_se(streq(strndupa(mem, len), "foo"));
605 free(mem);
606
607 assert_se(unbase32hexmem("CPNMUOG=", strlen("CPNMUOG="), true, &mem, &len) == 0);
608 assert_se(streq(strndupa(mem, len), "foob"));
609 free(mem);
610
611 assert_se(unbase32hexmem("CPNMUOJ1", strlen("CPNMUOJ1"), true, &mem, &len) == 0);
612 assert_se(streq(strndupa(mem, len), "fooba"));
613 free(mem);
614
615 assert_se(unbase32hexmem("CPNMUOJ1E8======", strlen("CPNMUOJ1E8======"), true, &mem, &len) == 0);
616 assert_se(streq(strndupa(mem, len), "foobar"));
617 free(mem);
618
619 assert_se(unbase32hexmem("A", strlen("A"), true, &mem, &len) == -EINVAL);
620 assert_se(unbase32hexmem("A=======", strlen("A======="), true, &mem, &len) == -EINVAL);
621 assert_se(unbase32hexmem("AAA=====", strlen("AAA====="), true, &mem, &len) == -EINVAL);
622 assert_se(unbase32hexmem("AAAAAA==", strlen("AAAAAA=="), true, &mem, &len) == -EINVAL);
623 assert_se(unbase32hexmem("AB======", strlen("AB======"), true, &mem, &len) == -EINVAL);
624 assert_se(unbase32hexmem("AAAB====", strlen("AAAB===="), true, &mem, &len) == -EINVAL);
625 assert_se(unbase32hexmem("AAAAB===", strlen("AAAAB==="), true, &mem, &len) == -EINVAL);
626 assert_se(unbase32hexmem("AAAAAAB=", strlen("AAAAAAB="), true, &mem, &len) == -EINVAL);
627
ff9265d0
DM
628 assert_se(unbase32hexmem("XPNMUOJ1", strlen("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
629 assert_se(unbase32hexmem("CXNMUOJ1", strlen("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
630 assert_se(unbase32hexmem("CPXMUOJ1", strlen("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
631 assert_se(unbase32hexmem("CPNXUOJ1", strlen("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
632 assert_se(unbase32hexmem("CPNMXOJ1", strlen("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
633 assert_se(unbase32hexmem("CPNMUXJ1", strlen("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
634 assert_se(unbase32hexmem("CPNMUOX1", strlen("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
635 assert_se(unbase32hexmem("CPNMUOJX", strlen("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
636
919a7f5f
TG
637 assert_se(unbase32hexmem("", strlen(""), false, &mem, &len) == 0);
638 assert_se(streq(strndupa(mem, len), ""));
639 free(mem);
640
641 assert_se(unbase32hexmem("CO", strlen("CO"), false, &mem, &len) == 0);
642 assert_se(streq(strndupa(mem, len), "f"));
643 free(mem);
644
645 assert_se(unbase32hexmem("CPNG", strlen("CPNG"), false, &mem, &len) == 0);
646 assert_se(streq(strndupa(mem, len), "fo"));
647 free(mem);
648
649 assert_se(unbase32hexmem("CPNMU", strlen("CPNMU"), false, &mem, &len) == 0);
650 assert_se(streq(strndupa(mem, len), "foo"));
651 free(mem);
652
653 assert_se(unbase32hexmem("CPNMUOG", strlen("CPNMUOG"), false, &mem, &len) == 0);
654 assert_se(streq(strndupa(mem, len), "foob"));
655 free(mem);
656
657 assert_se(unbase32hexmem("CPNMUOJ1", strlen("CPNMUOJ1"), false, &mem, &len) == 0);
658 assert_se(streq(strndupa(mem, len), "fooba"));
659 free(mem);
660
661 assert_se(unbase32hexmem("CPNMUOJ1E8", strlen("CPNMUOJ1E8"), false, &mem, &len) == 0);
662 assert_se(streq(strndupa(mem, len), "foobar"));
663 free(mem);
664
665 assert_se(unbase32hexmem("CPNMUOG=", strlen("CPNMUOG="), false, &mem, &len) == -EINVAL);
666 assert_se(unbase32hexmem("CPNMUOJ1E8======", strlen("CPNMUOJ1E8======"), false, &mem, &len) == -EINVAL);
667 assert_se(unbase32hexmem("A", strlen("A"), false, &mem, &len) == -EINVAL);
668 assert_se(unbase32hexmem("A", strlen("A"), false, &mem, &len) == -EINVAL);
669 assert_se(unbase32hexmem("AAA", strlen("AAA"), false, &mem, &len) == -EINVAL);
670 assert_se(unbase32hexmem("AAAAAA", strlen("AAAAAA"), false, &mem, &len) == -EINVAL);
671 assert_se(unbase32hexmem("AB", strlen("AB"), false, &mem, &len) == -EINVAL);
672 assert_se(unbase32hexmem("AAAB", strlen("AAAB"), false, &mem, &len) == -EINVAL);
673 assert_se(unbase32hexmem("AAAAB", strlen("AAAAB"), false, &mem, &len) == -EINVAL);
674 assert_se(unbase32hexmem("AAAAAAB", strlen("AAAAAAB"), false, &mem, &len) == -EINVAL);
675}
676
13a5d76b
TG
677/* https://tools.ietf.org/html/rfc4648#section-10 */
678static void test_base64mem(void) {
679 char *b64;
680
681 b64 = base64mem("", strlen(""));
682 assert_se(b64);
683 assert_se(streq(b64, ""));
684 free(b64);
685
686 b64 = base64mem("f", strlen("f"));
687 assert_se(b64);
688 assert_se(streq(b64, "Zg=="));
689 free(b64);
690
691 b64 = base64mem("fo", strlen("fo"));
692 assert_se(b64);
693 assert_se(streq(b64, "Zm8="));
694 free(b64);
695
696 b64 = base64mem("foo", strlen("foo"));
697 assert_se(b64);
698 assert_se(streq(b64, "Zm9v"));
699 free(b64);
700
701 b64 = base64mem("foob", strlen("foob"));
702 assert_se(b64);
703 assert_se(streq(b64, "Zm9vYg=="));
704 free(b64);
705
706 b64 = base64mem("fooba", strlen("fooba"));
707 assert_se(b64);
708 assert_se(streq(b64, "Zm9vYmE="));
709 free(b64);
710
711 b64 = base64mem("foobar", strlen("foobar"));
712 assert_se(b64);
713 assert_se(streq(b64, "Zm9vYmFy"));
714 free(b64);
715}
716
717static void test_unbase64mem(void) {
718 void *mem;
719 size_t len;
720
721 assert_se(unbase64mem("", strlen(""), &mem, &len) == 0);
722 assert_se(streq(strndupa(mem, len), ""));
723 free(mem);
724
725 assert_se(unbase64mem("Zg==", strlen("Zg=="), &mem, &len) == 0);
726 assert_se(streq(strndupa(mem, len), "f"));
727 free(mem);
728
729 assert_se(unbase64mem("Zm8=", strlen("Zm8="), &mem, &len) == 0);
730 assert_se(streq(strndupa(mem, len), "fo"));
731 free(mem);
732
733 assert_se(unbase64mem("Zm9v", strlen("Zm9v"), &mem, &len) == 0);
734 assert_se(streq(strndupa(mem, len), "foo"));
735 free(mem);
736
737 assert_se(unbase64mem("Zm9vYg==", strlen("Zm9vYg=="), &mem, &len) == 0);
738 assert_se(streq(strndupa(mem, len), "foob"));
739 free(mem);
740
741 assert_se(unbase64mem("Zm9vYmE=", strlen("Zm9vYmE="), &mem, &len) == 0);
742 assert_se(streq(strndupa(mem, len), "fooba"));
743 free(mem);
744
745 assert_se(unbase64mem("Zm9vYmFy", strlen("Zm9vYmFy"), &mem, &len) == 0);
746 assert_se(streq(strndupa(mem, len), "foobar"));
747 free(mem);
748
749 assert_se(unbase64mem("A", strlen("A"), &mem, &len) == -EINVAL);
750 assert_se(unbase64mem("A====", strlen("A===="), &mem, &len) == -EINVAL);
751 assert_se(unbase64mem("AAB==", strlen("AAB=="), &mem, &len) == -EINVAL);
752 assert_se(unbase64mem("AAAB=", strlen("AAAB="), &mem, &len) == -EINVAL);
753}
754
b4ecc959
TA
755static void test_cescape(void) {
756 _cleanup_free_ char *escaped;
e0a33e7b
LP
757
758 assert_se(escaped = cescape("abc\\\"\b\f\n\r\t\v\a\003\177\234\313"));
927be00c 759 assert_se(streq(escaped, "abc\\\\\\\"\\b\\f\\n\\r\\t\\v\\a\\003\\177\\234\\313"));
b4ecc959
TA
760}
761
762static void test_cunescape(void) {
763 _cleanup_free_ char *unescaped;
e0a33e7b 764
527b7a42
LP
765 assert_se(cunescape("abc\\\\\\\"\\b\\f\\a\\n\\r\\t\\v\\003\\177\\234\\313\\000\\x00", 0, &unescaped) < 0);
766 assert_se(cunescape("abc\\\\\\\"\\b\\f\\a\\n\\r\\t\\v\\003\\177\\234\\313\\000\\x00", UNESCAPE_RELAX, &unescaped) >= 0);
f3ee6297 767 assert_se(streq_ptr(unescaped, "abc\\\"\b\f\a\n\r\t\v\003\177\234\313\\000\\x00"));
97b11eed 768 unescaped = mfree(unescaped);
7f769619
ZJS
769
770 /* incomplete sequences */
527b7a42
LP
771 assert_se(cunescape("\\x0", 0, &unescaped) < 0);
772 assert_se(cunescape("\\x0", UNESCAPE_RELAX, &unescaped) >= 0);
7f769619 773 assert_se(streq_ptr(unescaped, "\\x0"));
97b11eed 774 unescaped = mfree(unescaped);
7f769619 775
527b7a42
LP
776 assert_se(cunescape("\\x", 0, &unescaped) < 0);
777 assert_se(cunescape("\\x", UNESCAPE_RELAX, &unescaped) >= 0);
7f769619 778 assert_se(streq_ptr(unescaped, "\\x"));
97b11eed 779 unescaped = mfree(unescaped);
7f769619 780
527b7a42
LP
781 assert_se(cunescape("\\", 0, &unescaped) < 0);
782 assert_se(cunescape("\\", UNESCAPE_RELAX, &unescaped) >= 0);
7f769619 783 assert_se(streq_ptr(unescaped, "\\"));
97b11eed 784 unescaped = mfree(unescaped);
7f769619 785
527b7a42
LP
786 assert_se(cunescape("\\11", 0, &unescaped) < 0);
787 assert_se(cunescape("\\11", UNESCAPE_RELAX, &unescaped) >= 0);
7f769619 788 assert_se(streq_ptr(unescaped, "\\11"));
97b11eed 789 unescaped = mfree(unescaped);
7f769619 790
527b7a42
LP
791 assert_se(cunescape("\\1", 0, &unescaped) < 0);
792 assert_se(cunescape("\\1", UNESCAPE_RELAX, &unescaped) >= 0);
7f769619 793 assert_se(streq_ptr(unescaped, "\\1"));
97b11eed 794 unescaped = mfree(unescaped);
f3ee6297
LP
795
796 assert_se(cunescape("\\u0000", 0, &unescaped) < 0);
797 assert_se(cunescape("\\u00DF\\U000000df\\u03a0\\U00000041", UNESCAPE_RELAX, &unescaped) >= 0);
798 assert_se(streq_ptr(unescaped, "ßßΠA"));
97b11eed 799 unescaped = mfree(unescaped);
3b51f8dd
DM
800
801 assert_se(cunescape("\\073", 0, &unescaped) >= 0);
802 assert_se(streq_ptr(unescaped, ";"));
b4ecc959
TA
803}
804
1ef04f0b 805static void test_foreach_word(void) {
a2a5291b 806 const char *word, *state;
1ef04f0b
TA
807 size_t l;
808 int i = 0;
809 const char test[] = "test abc d\te f ";
810 const char * const expected[] = {
811 "test",
812 "abc",
813 "d",
814 "e",
815 "f",
816 "",
817 NULL
818 };
819
a2a5291b
ZJS
820 FOREACH_WORD(word, l, test, state)
821 assert_se(strneq(expected[i++], word, l));
1ef04f0b
TA
822}
823
ba774317 824static void check(const char *test, char** expected, bool trailing) {
a2a5291b 825 const char *word, *state;
539ad707 826 size_t l;
1ef04f0b 827 int i = 0;
1ef04f0b 828
ba774317 829 printf("<<<%s>>>\n", test);
a2a5291b 830 FOREACH_WORD_QUOTED(word, l, test, state) {
1ef04f0b 831 _cleanup_free_ char *t = NULL;
539ad707 832
a2a5291b
ZJS
833 assert_se(t = strndup(word, l));
834 assert_se(strneq(expected[i++], word, l));
539ad707 835 printf("<%s>\n", t);
539ad707 836 }
ba774317 837 printf("<<<%s>>>\n", state);
e50221bf 838 assert_se(expected[i] == NULL);
ba774317
ZJS
839 assert_se(isempty(state) == !trailing);
840}
841
842static void test_foreach_word_quoted(void) {
843 check("test a b c 'd' e '' '' hhh '' '' \"a b c\"",
844 STRV_MAKE("test",
845 "a",
846 "b",
847 "c",
848 "d",
849 "e",
850 "",
851 "",
852 "hhh",
853 "",
854 "",
855 "a b c"),
856 false);
857
858 check("test \"xxx",
859 STRV_MAKE("test"),
860 true);
861
862 check("test\\",
863 STRV_MAKE_EMPTY,
864 true);
539ad707
TA
865}
866
0d585d82
TA
867static void test_memdup_multiply(void) {
868 int org[] = {1, 2, 3};
869 int *dup;
870
871 dup = (int*)memdup_multiply(org, sizeof(int), 3);
872
873 assert_se(dup);
874 assert_se(dup[0] == 1);
875 assert_se(dup[1] == 2);
876 assert_se(dup[2] == 3);
877 free(dup);
878}
879
144e51ec 880static void test_u64log2(void) {
bdf7026e
TA
881 assert_se(u64log2(0) == 0);
882 assert_se(u64log2(8) == 3);
883 assert_se(u64log2(9) == 3);
884 assert_se(u64log2(15) == 3);
885 assert_se(u64log2(16) == 4);
886 assert_se(u64log2(1024*1024) == 20);
887 assert_se(u64log2(1024*1024+5) == 20);
144e51ec
CR
888}
889
2a371001
ZJS
890static void test_protect_errno(void) {
891 errno = 12;
892 {
893 PROTECT_ERRNO;
894 errno = 11;
895 }
bdf7026e 896 assert_se(errno == 12);
2a371001
ZJS
897}
898
5556b5fe 899static void test_parse_size(void) {
59f448cf 900 uint64_t bytes;
b32ff512 901
5556b5fe 902 assert_se(parse_size("111", 1024, &bytes) == 0);
b32ff512
ZJS
903 assert_se(bytes == 111);
904
9480794b
ZJS
905 assert_se(parse_size("111.4", 1024, &bytes) == 0);
906 assert_se(bytes == 111);
907
5556b5fe 908 assert_se(parse_size(" 112 B", 1024, &bytes) == 0);
b32ff512
ZJS
909 assert_se(bytes == 112);
910
9480794b
ZJS
911 assert_se(parse_size(" 112.6 B", 1024, &bytes) == 0);
912 assert_se(bytes == 112);
913
914 assert_se(parse_size("3.5 K", 1024, &bytes) == 0);
915 assert_se(bytes == 3*1024 + 512);
916
917 assert_se(parse_size("3. K", 1024, &bytes) == 0);
918 assert_se(bytes == 3*1024);
919
920 assert_se(parse_size("3.0 K", 1024, &bytes) == 0);
b32ff512
ZJS
921 assert_se(bytes == 3*1024);
922
840292be 923 assert_se(parse_size("3. 0 K", 1024, &bytes) == -EINVAL);
b32ff512 924
9480794b
ZJS
925 assert_se(parse_size(" 4 M 11.5K", 1024, &bytes) == 0);
926 assert_se(bytes == 4*1024*1024 + 11 * 1024 + 512);
927
840292be
ZJS
928 assert_se(parse_size("3B3.5G", 1024, &bytes) == -EINVAL);
929
930 assert_se(parse_size("3.5G3B", 1024, &bytes) == 0);
9480794b 931 assert_se(bytes == 3ULL*1024*1024*1024 + 512*1024*1024 + 3);
b32ff512 932
840292be
ZJS
933 assert_se(parse_size("3.5G 4B", 1024, &bytes) == 0);
934 assert_se(bytes == 3ULL*1024*1024*1024 + 512*1024*1024 + 4);
935
936 assert_se(parse_size("3B3G4T", 1024, &bytes) == -EINVAL);
937
938 assert_se(parse_size("4T3G3B", 1024, &bytes) == 0);
939 assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3);
940
941 assert_se(parse_size(" 4 T 3 G 3 B", 1024, &bytes) == 0);
b32ff512
ZJS
942 assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3);
943
5556b5fe 944 assert_se(parse_size("12P", 1024, &bytes) == 0);
b32ff512
ZJS
945 assert_se(bytes == 12ULL * 1024*1024*1024*1024*1024);
946
840292be
ZJS
947 assert_se(parse_size("12P12P", 1024, &bytes) == -EINVAL);
948
5556b5fe 949 assert_se(parse_size("3E 2P", 1024, &bytes) == 0);
b32ff512
ZJS
950 assert_se(bytes == (3 * 1024 + 2ULL) * 1024*1024*1024*1024*1024);
951
5556b5fe 952 assert_se(parse_size("12X", 1024, &bytes) == -EINVAL);
b32ff512 953
9480794b
ZJS
954 assert_se(parse_size("12.5X", 1024, &bytes) == -EINVAL);
955
956 assert_se(parse_size("12.5e3", 1024, &bytes) == -EINVAL);
957
5556b5fe
LP
958 assert_se(parse_size("1024E", 1024, &bytes) == -ERANGE);
959 assert_se(parse_size("-1", 1024, &bytes) == -ERANGE);
960 assert_se(parse_size("-1024E", 1024, &bytes) == -ERANGE);
b32ff512 961
5556b5fe 962 assert_se(parse_size("-1024P", 1024, &bytes) == -ERANGE);
b32ff512 963
5556b5fe 964 assert_se(parse_size("-10B 20K", 1024, &bytes) == -ERANGE);
b32ff512
ZJS
965}
966
5f05235f
FB
967static void test_parse_cpu_set(void) {
968 cpu_set_t *c = NULL;
969 int ncpus;
970 int cpu;
971
972 /* Simple range (from CPUAffinity example) */
765d143b 973 ncpus = parse_cpu_set_and_warn("1 2", &c, NULL, "fake", 1, "CPUAffinity");
5f05235f
FB
974 assert_se(ncpus >= 1024);
975 assert_se(CPU_ISSET_S(1, CPU_ALLOC_SIZE(ncpus), c));
976 assert_se(CPU_ISSET_S(2, CPU_ALLOC_SIZE(ncpus), c));
977 assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 2);
978 c = mfree(c);
979
980 /* A more interesting range */
765d143b 981 ncpus = parse_cpu_set_and_warn("0 1 2 3 8 9 10 11", &c, NULL, "fake", 1, "CPUAffinity");
5f05235f
FB
982 assert_se(ncpus >= 1024);
983 assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 8);
984 for (cpu = 0; cpu < 4; cpu++)
985 assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
986 for (cpu = 8; cpu < 12; cpu++)
987 assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
988 c = mfree(c);
989
990 /* Quoted strings */
765d143b 991 ncpus = parse_cpu_set_and_warn("8 '9' 10 \"11\"", &c, NULL, "fake", 1, "CPUAffinity");
5f05235f
FB
992 assert_se(ncpus >= 1024);
993 assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 4);
994 for (cpu = 8; cpu < 12; cpu++)
995 assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
996 c = mfree(c);
997
998 /* Use commas as separators */
765d143b 999 ncpus = parse_cpu_set_and_warn("0,1,2,3 8,9,10,11", &c, NULL, "fake", 1, "CPUAffinity");
5f05235f
FB
1000 assert_se(ncpus < 0);
1001 assert_se(!c);
1002
1003 /* Ranges */
765d143b 1004 ncpus = parse_cpu_set_and_warn("0-3,8-11", &c, NULL, "fake", 1, "CPUAffinity");
5f05235f
FB
1005 assert_se(ncpus < 0);
1006 assert_se(!c);
1007
1008 /* Garbage */
765d143b 1009 ncpus = parse_cpu_set_and_warn("0 1 2 3 garbage", &c, NULL, "fake", 1, "CPUAffinity");
5f05235f
FB
1010 assert_se(ncpus < 0);
1011 assert_se(!c);
1012
1013 /* Empty string */
1014 c = NULL;
765d143b 1015 ncpus = parse_cpu_set_and_warn("", &c, NULL, "fake", 1, "CPUAffinity");
5f05235f
FB
1016 assert_se(ncpus == 0); /* empty string returns 0 */
1017 assert_se(!c);
1018
1019 /* Runnaway quoted string */
765d143b 1020 ncpus = parse_cpu_set_and_warn("0 1 2 3 \"4 5 6 7 ", &c, NULL, "fake", 1, "CPUAffinity");
5f05235f
FB
1021 assert_se(ncpus < 0);
1022 assert_se(!c);
1023}
1024
59f448cf
LP
1025static void test_config_parse_iec_uint64(void) {
1026 uint64_t offset = 0;
1027 assert_se(config_parse_iec_uint64(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4M", &offset, NULL) == 0);
9480794b
ZJS
1028 assert_se(offset == 4 * 1024 * 1024);
1029
59f448cf 1030 assert_se(config_parse_iec_uint64(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4.5M", &offset, NULL) == 0);
9480794b
ZJS
1031}
1032
b4ecc959
TA
1033static void test_strextend(void) {
1034 _cleanup_free_ char *str = strdup("0123");
1035 strextend(&str, "456", "78", "9", NULL);
1036 assert_se(streq(str, "0123456789"));
1037}
1038
1039static void test_strrep(void) {
1040 _cleanup_free_ char *one, *three, *zero;
1041 one = strrep("waldo", 1);
1042 three = strrep("waldo", 3);
1043 zero = strrep("waldo", 0);
1044
1045 assert_se(streq(one, "waldo"));
1046 assert_se(streq(three, "waldowaldowaldo"));
1047 assert_se(streq(zero, ""));
1048}
1049
d4ac85c6
LP
1050static void test_split_pair(void) {
1051 _cleanup_free_ char *a = NULL, *b = NULL;
1052
1053 assert_se(split_pair("", "", &a, &b) == -EINVAL);
1054 assert_se(split_pair("foo=bar", "", &a, &b) == -EINVAL);
1055 assert_se(split_pair("", "=", &a, &b) == -EINVAL);
1056 assert_se(split_pair("foo=bar", "=", &a, &b) >= 0);
1057 assert_se(streq(a, "foo"));
1058 assert_se(streq(b, "bar"));
1059 free(a);
1060 free(b);
1061 assert_se(split_pair("==", "==", &a, &b) >= 0);
1062 assert_se(streq(a, ""));
1063 assert_se(streq(b, ""));
1064 free(a);
1065 free(b);
1066
1067 assert_se(split_pair("===", "==", &a, &b) >= 0);
1068 assert_se(streq(a, ""));
1069 assert_se(streq(b, "="));
1070}
1071
22f5f628
DR
1072static void test_fstab_node_to_udev_node(void) {
1073 char *n;
1074
1075 n = fstab_node_to_udev_node("LABEL=applé/jack");
1076 puts(n);
1077 assert_se(streq(n, "/dev/disk/by-label/applé\\x2fjack"));
1078 free(n);
1079
1080 n = fstab_node_to_udev_node("PARTLABEL=pinkié pie");
1081 puts(n);
1082 assert_se(streq(n, "/dev/disk/by-partlabel/pinkié\\x20pie"));
1083 free(n);
1084
1085 n = fstab_node_to_udev_node("UUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
1086 puts(n);
1087 assert_se(streq(n, "/dev/disk/by-uuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
1088 free(n);
1089
1090 n = fstab_node_to_udev_node("PARTUUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
1091 puts(n);
1092 assert_se(streq(n, "/dev/disk/by-partuuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
1093 free(n);
1094
22f5f628
DR
1095 n = fstab_node_to_udev_node("PONIES=awesome");
1096 puts(n);
1097 assert_se(streq(n, "PONIES=awesome"));
1098 free(n);
1099
1100 n = fstab_node_to_udev_node("/dev/xda1");
1101 puts(n);
1102 assert_se(streq(n, "/dev/xda1"));
1103 free(n);
1104}
1105
893fa014
ZJS
1106static void test_get_files_in_directory(void) {
1107 _cleanup_strv_free_ char **l = NULL, **t = NULL;
1108
1109 assert_se(get_files_in_directory("/tmp", &l) >= 0);
510b857f 1110 assert_se(get_files_in_directory(".", &t) >= 0);
893fa014
ZJS
1111 assert_se(get_files_in_directory(".", NULL) >= 0);
1112}
1113
cabb7806
LP
1114static void test_in_set(void) {
1115 assert_se(IN_SET(1, 1));
1116 assert_se(IN_SET(1, 1, 2, 3, 4));
1117 assert_se(IN_SET(2, 1, 2, 3, 4));
1118 assert_se(IN_SET(3, 1, 2, 3, 4));
1119 assert_se(IN_SET(4, 1, 2, 3, 4));
1120 assert_se(!IN_SET(0, 1));
1121 assert_se(!IN_SET(0, 1, 2, 3, 4));
1122}
1123
87b02843
ZJS
1124static void test_writing_tmpfile(void) {
1125 char name[] = "/tmp/test-systemd_writing_tmpfile.XXXXXX";
39883f62 1126 _cleanup_free_ char *contents = NULL;
65b3903f
ZJS
1127 size_t size;
1128 int fd, r;
65b3903f 1129 struct iovec iov[3];
39883f62 1130
65b3903f
ZJS
1131 IOVEC_SET_STRING(iov[0], "abc\n");
1132 IOVEC_SET_STRING(iov[1], ALPHANUMERICAL "\n");
1133 IOVEC_SET_STRING(iov[2], "");
1134
2d5bdf5b 1135 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
87b02843 1136 printf("tmpfile: %s", name);
65b3903f 1137
87b02843 1138 r = writev(fd, iov, 3);
bdf7026e 1139 assert_se(r >= 0);
65b3903f
ZJS
1140
1141 r = read_full_file(name, &contents, &size);
bdf7026e 1142 assert_se(r == 0);
65b3903f 1143 printf("contents: %s", contents);
bdf7026e 1144 assert_se(streq(contents, "abc\n" ALPHANUMERICAL "\n"));
40edd236
RC
1145
1146 unlink(name);
65b3903f
ZJS
1147}
1148
29bfbcd6
LP
1149static void test_hexdump(void) {
1150 uint8_t data[146];
1151 unsigned i;
1152
1153 hexdump(stdout, NULL, 0);
1154 hexdump(stdout, "", 0);
1155 hexdump(stdout, "", 1);
1156 hexdump(stdout, "x", 1);
1157 hexdump(stdout, "x", 2);
1158 hexdump(stdout, "foobar", 7);
1159 hexdump(stdout, "f\nobar", 7);
1160 hexdump(stdout, "xxxxxxxxxxxxxxxxxxxxyz", 23);
1161
1162 for (i = 0; i < ELEMENTSOF(data); i++)
1163 data[i] = i*2;
1164
1165 hexdump(stdout, data, sizeof(data));
1166}
1167
8fe90522
ZJS
1168static void test_log2i(void) {
1169 assert_se(log2i(1) == 0);
1170 assert_se(log2i(2) == 1);
1171 assert_se(log2i(3) == 1);
1172 assert_se(log2i(4) == 2);
1173 assert_se(log2i(32) == 5);
1174 assert_se(log2i(33) == 5);
1175 assert_se(log2i(63) == 5);
1176 assert_se(log2i(INT_MAX) == sizeof(int)*8-2);
1177}
1178
c4a7b2c5
LP
1179static void test_foreach_string(void) {
1180 const char * const t[] = {
1181 "foo",
1182 "bar",
1183 "waldo",
1184 NULL
1185 };
1186 const char *x;
1187 unsigned i = 0;
1188
1189 FOREACH_STRING(x, "foo", "bar", "waldo")
1190 assert_se(streq_ptr(t[i++], x));
1191
1192 assert_se(i == 3);
1193
1194 FOREACH_STRING(x, "zzz")
1195 assert_se(streq(x, "zzz"));
1196}
1197
ae6c3cc0 1198static void test_filename_is_valid(void) {
927be00c
RC
1199 char foo[FILENAME_MAX+2];
1200 int i;
1201
ae6c3cc0
LP
1202 assert_se(!filename_is_valid(""));
1203 assert_se(!filename_is_valid("/bar/foo"));
1204 assert_se(!filename_is_valid("/"));
1205 assert_se(!filename_is_valid("."));
1206 assert_se(!filename_is_valid(".."));
927be00c
RC
1207
1208 for (i=0; i<FILENAME_MAX+1; i++)
1209 foo[i] = 'a';
1210 foo[FILENAME_MAX+1] = '\0';
1211
ae6c3cc0 1212 assert_se(!filename_is_valid(foo));
927be00c 1213
ae6c3cc0
LP
1214 assert_se(filename_is_valid("foo_bar-333"));
1215 assert_se(filename_is_valid("o.o"));
927be00c
RC
1216}
1217
1cb1767a
ZJS
1218static void test_string_has_cc(void) {
1219 assert_se(string_has_cc("abc\1", NULL));
1220 assert_se(string_has_cc("abc\x7f", NULL));
1221 assert_se(string_has_cc("abc\x7f", NULL));
1222 assert_se(string_has_cc("abc\t\x7f", "\t"));
1223 assert_se(string_has_cc("abc\t\x7f", "\t"));
1224 assert_se(string_has_cc("\x7f", "\t"));
1225 assert_se(string_has_cc("\x7f", "\t\a"));
1226
1227 assert_se(!string_has_cc("abc\t\t", "\t"));
1228 assert_se(!string_has_cc("abc\t\t\a", "\t\a"));
1229 assert_se(!string_has_cc("a\ab\tc", "\t\a"));
1230}
1231
927be00c
RC
1232static void test_ascii_strlower(void) {
1233 char a[] = "AabBcC Jk Ii Od LKJJJ kkd LK";
1234 assert_se(streq(ascii_strlower(a), "aabbcc jk ii od lkjjj kkd lk"));
1235}
1236
1237static void test_files_same(void) {
1238 _cleanup_close_ int fd = -1;
1239 char name[] = "/tmp/test-files_same.XXXXXX";
1240 char name_alias[] = "/tmp/test-files_same.alias";
1241
1242 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1243 assert_se(fd >= 0);
1244 assert_se(symlink(name, name_alias) >= 0);
1245
1246 assert_se(files_same(name, name));
1247 assert_se(files_same(name, name_alias));
1248
1249 unlink(name);
1250 unlink(name_alias);
1251}
1252
1253static void test_is_valid_documentation_url(void) {
a2e03378
LP
1254 assert_se(documentation_url_is_valid("http://www.freedesktop.org/wiki/Software/systemd"));
1255 assert_se(documentation_url_is_valid("https://www.kernel.org/doc/Documentation/binfmt_misc.txt"));
1256 assert_se(documentation_url_is_valid("file:/foo/foo"));
1257 assert_se(documentation_url_is_valid("man:systemd.special(7)"));
1258 assert_se(documentation_url_is_valid("info:bar"));
1259
1260 assert_se(!documentation_url_is_valid("foo:"));
1261 assert_se(!documentation_url_is_valid("info:"));
1262 assert_se(!documentation_url_is_valid(""));
927be00c
RC
1263}
1264
1265static void test_file_in_same_dir(void) {
eee84633
DH
1266 char *t;
1267
1268 t = file_in_same_dir("/", "a");
1269 assert_se(streq(t, "/a"));
1270 free(t);
1271
1272 t = file_in_same_dir("/", "/a");
1273 assert_se(streq(t, "/a"));
1274 free(t);
1275
1276 t = file_in_same_dir("", "a");
1277 assert_se(streq(t, "a"));
1278 free(t);
1279
1280 t = file_in_same_dir("a/", "a");
1281 assert_se(streq(t, "a/a"));
1282 free(t);
1283
1284 t = file_in_same_dir("bar/foo", "bar");
1285 assert_se(streq(t, "bar/bar"));
1286 free(t);
927be00c
RC
1287}
1288
1289static void test_endswith(void) {
1290 assert_se(endswith("foobar", "bar"));
1291 assert_se(endswith("foobar", ""));
1292 assert_se(endswith("foobar", "foobar"));
1293 assert_se(endswith("", ""));
1294
1295 assert_se(!endswith("foobar", "foo"));
1296 assert_se(!endswith("foobar", "foobarfoofoo"));
1297}
1298
ff9265d0
DM
1299static void test_endswith_no_case(void) {
1300 assert_se(endswith_no_case("fooBAR", "bar"));
1301 assert_se(endswith_no_case("foobar", ""));
1302 assert_se(endswith_no_case("foobar", "FOOBAR"));
1303 assert_se(endswith_no_case("", ""));
1304
1305 assert_se(!endswith_no_case("foobar", "FOO"));
1306 assert_se(!endswith_no_case("foobar", "FOOBARFOOFOO"));
1307}
1308
927be00c
RC
1309static void test_close_nointr(void) {
1310 char name[] = "/tmp/test-test-close_nointr.XXXXXX";
1311 int fd;
1312
1313 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1314 assert_se(fd >= 0);
1315 assert_se(close_nointr(fd) >= 0);
1316 assert_se(close_nointr(fd) < 0);
1317
1318 unlink(name);
1319}
1320
1321
1322static void test_unlink_noerrno(void) {
1323 char name[] = "/tmp/test-close_nointr.XXXXXX";
1324 int fd;
1325
1326 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1327 assert_se(fd >= 0);
1328 assert_se(close_nointr(fd) >= 0);
1329
1330 {
1331 PROTECT_ERRNO;
1332 errno = -42;
1333 assert_se(unlink_noerrno(name) >= 0);
1334 assert_se(errno == -42);
1335 assert_se(unlink_noerrno(name) < 0);
1336 assert_se(errno == -42);
1337 }
1338}
1339
1340static void test_readlink_and_make_absolute(void) {
1341 char tempdir[] = "/tmp/test-readlink_and_make_absolute";
1342 char name[] = "/tmp/test-readlink_and_make_absolute/original";
1343 char name2[] = "test-readlink_and_make_absolute/original";
1344 char name_alias[] = "/tmp/test-readlink_and_make_absolute-alias";
1345 char *r = NULL;
1346
684fc892 1347 assert_se(mkdir_safe(tempdir, 0755, getuid(), getgid()) >= 0);
927be00c
RC
1348 assert_se(touch(name) >= 0);
1349
1350 assert_se(symlink(name, name_alias) >= 0);
1351 assert_se(readlink_and_make_absolute(name_alias, &r) >= 0);
1352 assert_se(streq(r, name));
1353 free(r);
1354 assert_se(unlink(name_alias) >= 0);
1355
1356 assert_se(chdir(tempdir) >= 0);
1357 assert_se(symlink(name2, name_alias) >= 0);
1358 assert_se(readlink_and_make_absolute(name_alias, &r) >= 0);
1359 assert_se(streq(r, name));
1360 free(r);
1361 assert_se(unlink(name_alias) >= 0);
1362
c6878637 1363 assert_se(rm_rf(tempdir, REMOVE_ROOT|REMOVE_PHYSICAL) >= 0);
927be00c
RC
1364}
1365
927be00c
RC
1366static void test_ignore_signals(void) {
1367 assert_se(ignore_signals(SIGINT, -1) >= 0);
1368 assert_se(kill(getpid(), SIGINT) >= 0);
1369 assert_se(ignore_signals(SIGUSR1, SIGUSR2, SIGTERM, SIGPIPE, -1) >= 0);
1370 assert_se(kill(getpid(), SIGUSR1) >= 0);
1371 assert_se(kill(getpid(), SIGUSR2) >= 0);
1372 assert_se(kill(getpid(), SIGTERM) >= 0);
1373 assert_se(kill(getpid(), SIGPIPE) >= 0);
1374 assert_se(default_signals(SIGINT, SIGUSR1, SIGUSR2, SIGTERM, SIGPIPE, -1) >= 0);
1375}
1376
1377static void test_strshorten(void) {
1378 char s[] = "foobar";
1379
1380 assert_se(strlen(strshorten(s, 6)) == 6);
1381 assert_se(strlen(strshorten(s, 12)) == 6);
1382 assert_se(strlen(strshorten(s, 2)) == 2);
1383 assert_se(strlen(strshorten(s, 0)) == 0);
1384}
1385
63c372cb 1386static void test_strjoina(void) {
8085f163
DR
1387 char *actual;
1388
63c372cb 1389 actual = strjoina("", "foo", "bar");
8085f163
DR
1390 assert_se(streq(actual, "foobar"));
1391
63c372cb 1392 actual = strjoina("foo", "bar", "baz");
8085f163
DR
1393 assert_se(streq(actual, "foobarbaz"));
1394
63c372cb 1395 actual = strjoina("foo", "", "bar", "baz");
8085f163 1396 assert_se(streq(actual, "foobarbaz"));
63c372cb
LP
1397
1398 actual = strjoina("foo");
1399 assert_se(streq(actual, "foo"));
1400
1401 actual = strjoina(NULL);
1402 assert_se(streq(actual, ""));
1403
1404 actual = strjoina(NULL, "foo");
1405 assert_se(streq(actual, ""));
1406
1407 actual = strjoina("foo", NULL, "bar");
1408 assert_se(streq(actual, "foo"));
8085f163
DR
1409}
1410
8852362b
RC
1411static void test_is_symlink(void) {
1412 char name[] = "/tmp/test-is_symlink.XXXXXX";
1413 char name_link[] = "/tmp/test-is_symlink.link";
1414 _cleanup_close_ int fd = -1;
1415
1416 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1417 assert_se(fd >= 0);
1418 assert_se(symlink(name, name_link) >= 0);
1419
1420 assert_se(is_symlink(name) == 0);
1421 assert_se(is_symlink(name_link) == 1);
1422 assert_se(is_symlink("/a/file/which/does/not/exist/i/guess") < 0);
1423
1424
1425 unlink(name);
1426 unlink(name_link);
1427}
1428
8852362b
RC
1429static void test_search_and_fopen(void) {
1430 const char *dirs[] = {"/tmp/foo/bar", "/tmp", NULL};
1431 char name[] = "/tmp/test-search_and_fopen.XXXXXX";
1432 int fd = -1;
1433 int r;
1434 FILE *f;
1435
1436 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1437 assert_se(fd >= 0);
1438 close(fd);
1439
1440 r = search_and_fopen(basename(name), "r", NULL, dirs, &f);
1441 assert_se(r >= 0);
1442 fclose(f);
1443
1444 r = search_and_fopen(name, "r", NULL, dirs, &f);
1445 assert_se(r >= 0);
1446 fclose(f);
1447
1448 r = search_and_fopen(basename(name), "r", "/", dirs, &f);
1449 assert_se(r >= 0);
1450 fclose(f);
1451
1452 r = search_and_fopen("/a/file/which/does/not/exist/i/guess", "r", NULL, dirs, &f);
1453 assert_se(r < 0);
1454 r = search_and_fopen("afilewhichdoesnotexistiguess", "r", NULL, dirs, &f);
1455 assert_se(r < 0);
1456
1457 r = unlink(name);
1458 assert_se(r == 0);
1459
1460 r = search_and_fopen(basename(name), "r", NULL, dirs, &f);
1461 assert_se(r < 0);
1462}
1463
1464
1465static void test_search_and_fopen_nulstr(void) {
1466 const char dirs[] = "/tmp/foo/bar\0/tmp\0";
1467 char name[] = "/tmp/test-search_and_fopen.XXXXXX";
1468 int fd = -1;
1469 int r;
1470 FILE *f;
1471
1472 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1473 assert_se(fd >= 0);
1474 close(fd);
1475
1476 r = search_and_fopen_nulstr(basename(name), "r", NULL, dirs, &f);
1477 assert_se(r >= 0);
1478 fclose(f);
1479
1480 r = search_and_fopen_nulstr(name, "r", NULL, dirs, &f);
1481 assert_se(r >= 0);
1482 fclose(f);
1483
1484 r = search_and_fopen_nulstr("/a/file/which/does/not/exist/i/guess", "r", NULL, dirs, &f);
1485 assert_se(r < 0);
1486 r = search_and_fopen_nulstr("afilewhichdoesnotexistiguess", "r", NULL, dirs, &f);
1487 assert_se(r < 0);
1488
1489 r = unlink(name);
1490 assert_se(r == 0);
1491
1492 r = search_and_fopen_nulstr(basename(name), "r", NULL, dirs, &f);
1493 assert_se(r < 0);
1494}
1495
1496static void test_glob_exists(void) {
1497 char name[] = "/tmp/test-glob_exists.XXXXXX";
1498 int fd = -1;
1499 int r;
1500
1501 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1502 assert_se(fd >= 0);
1503 close(fd);
1504
1505 r = glob_exists("/tmp/test-glob_exists*");
1506 assert_se(r == 1);
1507
1508 r = unlink(name);
1509 assert_se(r == 0);
1510 r = glob_exists("/tmp/test-glob_exists*");
1511 assert_se(r == 0);
1512}
1513
1514static void test_execute_directory(void) {
aac7766c
ZJS
1515 char template_lo[] = "/tmp/test-readlink_and_make_absolute-lo.XXXXXXX";
1516 char template_hi[] = "/tmp/test-readlink_and_make_absolute-hi.XXXXXXX";
76f282c6 1517 const char * dirs[] = {template_hi, template_lo, NULL};
aac7766c
ZJS
1518 const char *name, *name2, *name3, *overridden, *override, *masked, *mask;
1519
1520 assert_se(mkdtemp(template_lo));
1521 assert_se(mkdtemp(template_hi));
1522
63c372cb
LP
1523 name = strjoina(template_lo, "/script");
1524 name2 = strjoina(template_hi, "/script2");
1525 name3 = strjoina(template_lo, "/useless");
1526 overridden = strjoina(template_lo, "/overridden");
1527 override = strjoina(template_hi, "/overridden");
1528 masked = strjoina(template_lo, "/masked");
1529 mask = strjoina(template_hi, "/masked");
e801700e 1530
4c1fc3e4
DM
1531 assert_se(write_string_file(name, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/it_works", WRITE_STRING_FILE_CREATE) == 0);
1532 assert_se(write_string_file(name2, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/it_works2", WRITE_STRING_FILE_CREATE) == 0);
1533 assert_se(write_string_file(overridden, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/failed", WRITE_STRING_FILE_CREATE) == 0);
1534 assert_se(write_string_file(override, "#!/bin/sh\necho 'Executing '$0", WRITE_STRING_FILE_CREATE) == 0);
1535 assert_se(write_string_file(masked, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/failed", WRITE_STRING_FILE_CREATE) == 0);
aac7766c 1536 assert_se(symlink("/dev/null", mask) == 0);
8852362b
RC
1537 assert_se(chmod(name, 0755) == 0);
1538 assert_se(chmod(name2, 0755) == 0);
aac7766c
ZJS
1539 assert_se(chmod(overridden, 0755) == 0);
1540 assert_se(chmod(override, 0755) == 0);
1541 assert_se(chmod(masked, 0755) == 0);
8852362b
RC
1542 assert_se(touch(name3) >= 0);
1543
e801700e 1544 execute_directories(dirs, DEFAULT_TIMEOUT_USEC, NULL);
aac7766c 1545
0c0cdb06 1546 assert_se(chdir(template_lo) == 0);
e801700e 1547 assert_se(access("it_works", F_OK) >= 0);
aac7766c
ZJS
1548 assert_se(access("failed", F_OK) < 0);
1549
0c0cdb06 1550 assert_se(chdir(template_hi) == 0);
e801700e 1551 assert_se(access("it_works2", F_OK) >= 0);
aac7766c 1552 assert_se(access("failed", F_OK) < 0);
8852362b 1553
c6878637
LP
1554 (void) rm_rf(template_lo, REMOVE_ROOT|REMOVE_PHYSICAL);
1555 (void) rm_rf(template_hi, REMOVE_ROOT|REMOVE_PHYSICAL);
8852362b
RC
1556}
1557
68685607 1558static void test_extract_first_word(void) {
7629889c
LP
1559 const char *p, *original;
1560 char *t;
1561
1562 p = original = "foobar waldo";
68685607 1563 assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
7629889c
LP
1564 assert_se(streq(t, "foobar"));
1565 free(t);
1566 assert_se(p == original + 7);
1567
68685607 1568 assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
7629889c
LP
1569 assert_se(streq(t, "waldo"));
1570 free(t);
4b1c1753 1571 assert_se(isempty(p));
7629889c 1572
68685607 1573 assert_se(extract_first_word(&p, &t, NULL, 0) == 0);
7629889c 1574 assert_se(!t);
4b1c1753 1575 assert_se(isempty(p));
7629889c
LP
1576
1577 p = original = "\"foobar\" \'waldo\'";
68685607 1578 assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
12ba2c44 1579 assert_se(streq(t, "\"foobar\""));
7629889c
LP
1580 free(t);
1581 assert_se(p == original + 9);
1582
68685607 1583 assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
12ba2c44
RM
1584 assert_se(streq(t, "\'waldo\'"));
1585 free(t);
1586 assert_se(isempty(p));
1587
1588 assert_se(extract_first_word(&p, &t, NULL, 0) == 0);
1589 assert_se(!t);
1590 assert_se(isempty(p));
1591
1592 p = original = "\"foobar\" \'waldo\'";
1593 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) > 0);
1594 assert_se(streq(t, "foobar"));
1595 free(t);
1596 assert_se(p == original + 9);
1597
1598 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) > 0);
7629889c
LP
1599 assert_se(streq(t, "waldo"));
1600 free(t);
4b1c1753 1601 assert_se(isempty(p));
7629889c 1602
68685607 1603 assert_se(extract_first_word(&p, &t, NULL, 0) == 0);
7629889c 1604 assert_se(!t);
4b1c1753 1605 assert_se(isempty(p));
7629889c
LP
1606
1607 p = original = "\"";
12ba2c44
RM
1608 assert_se(extract_first_word(&p, &t, NULL, 0) == 1);
1609 assert_se(streq(t, "\""));
21e5a0be 1610 free(t);
12ba2c44
RM
1611 assert_se(isempty(p));
1612
1613 p = original = "\"";
1614 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) == -EINVAL);
7629889c
LP
1615 assert_se(p == original + 1);
1616
1617 p = original = "\'";
12ba2c44
RM
1618 assert_se(extract_first_word(&p, &t, NULL, 0) == 1);
1619 assert_se(streq(t, "\'"));
21e5a0be 1620 free(t);
12ba2c44
RM
1621 assert_se(isempty(p));
1622
1623 p = original = "\'";
1624 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) == -EINVAL);
7629889c
LP
1625 assert_se(p == original + 1);
1626
f32d2db1 1627 p = original = "\'fooo";
12ba2c44
RM
1628 assert_se(extract_first_word(&p, &t, NULL, 0) == 1);
1629 assert_se(streq(t, "\'fooo"));
21e5a0be 1630 free(t);
12ba2c44
RM
1631 assert_se(isempty(p));
1632
1633 p = original = "\'fooo";
1634 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) == -EINVAL);
f32d2db1
LP
1635 assert_se(p == original + 5);
1636
1637 p = original = "\'fooo";
12ba2c44 1638 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_RELAX) > 0);
f32d2db1 1639 assert_se(streq(t, "fooo"));
e1ba963f 1640 free(t);
4b1c1753 1641 assert_se(isempty(p));
f32d2db1 1642
9e44f56b
EV
1643 p = original = "\"fooo";
1644 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_RELAX) > 0);
1645 assert_se(streq(t, "fooo"));
1646 free(t);
1647 assert_se(isempty(p));
1648
7629889c 1649 p = original = "yay\'foo\'bar";
68685607 1650 assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
12ba2c44
RM
1651 assert_se(streq(t, "yay\'foo\'bar"));
1652 free(t);
1653 assert_se(isempty(p));
1654
1655 p = original = "yay\'foo\'bar";
1656 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) > 0);
7629889c
LP
1657 assert_se(streq(t, "yayfoobar"));
1658 free(t);
4b1c1753 1659 assert_se(isempty(p));
7629889c
LP
1660
1661 p = original = " foobar ";
68685607 1662 assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
7629889c
LP
1663 assert_se(streq(t, "foobar"));
1664 free(t);
4b1c1753 1665 assert_se(isempty(p));
4034a06d
LP
1666
1667 p = original = " foo\\ba\\x6ar ";
68685607 1668 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE) > 0);
4034a06d
LP
1669 assert_se(streq(t, "foo\ba\x6ar"));
1670 free(t);
4b1c1753 1671 assert_se(isempty(p));
4034a06d
LP
1672
1673 p = original = " foo\\ba\\x6ar ";
68685607 1674 assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
4034a06d
LP
1675 assert_se(streq(t, "foobax6ar"));
1676 free(t);
4b1c1753 1677 assert_se(isempty(p));
8ebac1f9
LP
1678
1679 p = original = " f\\u00f6o \"pi\\U0001F4A9le\" ";
68685607 1680 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE) > 0);
8ebac1f9
LP
1681 assert_se(streq(t, "föo"));
1682 free(t);
1683 assert_se(p == original + 13);
1684
12ba2c44 1685 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE) > 0);
8ebac1f9
LP
1686 assert_se(streq(t, "pi\360\237\222\251le"));
1687 free(t);
4b1c1753 1688 assert_se(isempty(p));
d6293c07
FB
1689
1690 p = original = "fooo\\";
68685607 1691 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_RELAX) > 0);
d6293c07
FB
1692 assert_se(streq(t, "fooo"));
1693 free(t);
4b1c1753 1694 assert_se(isempty(p));
d6293c07
FB
1695
1696 p = original = "fooo\\";
68685607 1697 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE_RELAX) > 0);
d6293c07
FB
1698 assert_se(streq(t, "fooo\\"));
1699 free(t);
4b1c1753 1700 assert_se(isempty(p));
d6293c07
FB
1701
1702 p = original = "fooo\\";
68685607 1703 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE_RELAX|EXTRACT_RELAX) > 0);
d6293c07
FB
1704 assert_se(streq(t, "fooo\\"));
1705 free(t);
4b1c1753 1706 assert_se(isempty(p));
d6293c07
FB
1707
1708 p = original = "fooo\\";
68685607 1709 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE|EXTRACT_CUNESCAPE_RELAX) > 0);
d6293c07
FB
1710 assert_se(streq(t, "fooo\\"));
1711 free(t);
4b1c1753 1712 assert_se(isempty(p));
d6293c07
FB
1713
1714 p = original = "\"foo\\";
68685607 1715 assert_se(extract_first_word(&p, &t, NULL, 0) == -EINVAL);
d6293c07
FB
1716 assert_se(p == original + 5);
1717
1718 p = original = "\"foo\\";
12ba2c44 1719 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_RELAX) > 0);
d6293c07
FB
1720 assert_se(streq(t, "foo"));
1721 free(t);
4b1c1753 1722 assert_se(isempty(p));
d6293c07 1723
68685607
RM
1724 p = original = "foo::bar";
1725 assert_se(extract_first_word(&p, &t, ":", 0) == 1);
1726 assert_se(streq(t, "foo"));
1727 free(t);
1728 assert_se(p == original + 5);
1729
1730 assert_se(extract_first_word(&p, &t, ":", 0) == 1);
1731 assert_se(streq(t, "bar"));
1732 free(t);
1733 assert_se(isempty(p));
1734
1735 assert_se(extract_first_word(&p, &t, ":", 0) == 0);
1736 assert_se(!t);
1737 assert_se(isempty(p));
1738
1739 p = original = "foo\\:bar::waldo";
1740 assert_se(extract_first_word(&p, &t, ":", 0) == 1);
1741 assert_se(streq(t, "foo:bar"));
1742 free(t);
1743 assert_se(p == original + 10);
1744
1745 assert_se(extract_first_word(&p, &t, ":", 0) == 1);
1746 assert_se(streq(t, "waldo"));
1747 free(t);
1748 assert_se(isempty(p));
1749
1750 assert_se(extract_first_word(&p, &t, ":", 0) == 0);
1751 assert_se(!t);
1752 assert_se(isempty(p));
1753
d6293c07 1754 p = original = "\"foo\\";
12ba2c44 1755 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE_RELAX) == -EINVAL);
d6293c07
FB
1756 assert_se(p == original + 5);
1757
1758 p = original = "\"foo\\";
12ba2c44 1759 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE_RELAX|EXTRACT_RELAX) > 0);
d6293c07
FB
1760 assert_se(streq(t, "foo\\"));
1761 free(t);
4b1c1753 1762 assert_se(isempty(p));
d6293c07
FB
1763
1764 p = original = "\"foo\\";
12ba2c44 1765 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE|EXTRACT_CUNESCAPE_RELAX|EXTRACT_RELAX) > 0);
d6293c07
FB
1766 assert_se(streq(t, "foo\\"));
1767 free(t);
4b1c1753 1768 assert_se(isempty(p));
d6293c07
FB
1769
1770 p = original = "fooo\\ bar quux";
68685607 1771 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_RELAX) > 0);
d6293c07
FB
1772 assert_se(streq(t, "fooo bar"));
1773 free(t);
1774 assert_se(p == original + 10);
1775
1776 p = original = "fooo\\ bar quux";
68685607 1777 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE_RELAX) > 0);
d6293c07
FB
1778 assert_se(streq(t, "fooo bar"));
1779 free(t);
1780 assert_se(p == original + 10);
1781
1782 p = original = "fooo\\ bar quux";
68685607 1783 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE_RELAX|EXTRACT_RELAX) > 0);
d6293c07
FB
1784 assert_se(streq(t, "fooo bar"));
1785 free(t);
1786 assert_se(p == original + 10);
1787
1788 p = original = "fooo\\ bar quux";
68685607 1789 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE) == -EINVAL);
d6293c07
FB
1790 assert_se(p == original + 5);
1791
1792 p = original = "fooo\\ bar quux";
68685607 1793 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE|EXTRACT_CUNESCAPE_RELAX) > 0);
d6293c07
FB
1794 assert_se(streq(t, "fooo\\ bar"));
1795 free(t);
1796 assert_se(p == original + 10);
1797
1798 p = original = "\\w+@\\K[\\d.]+";
68685607 1799 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE) == -EINVAL);
d6293c07
FB
1800 assert_se(p == original + 1);
1801
1802 p = original = "\\w+@\\K[\\d.]+";
68685607 1803 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE|EXTRACT_CUNESCAPE_RELAX) > 0);
d6293c07
FB
1804 assert_se(streq(t, "\\w+@\\K[\\d.]+"));
1805 free(t);
4b1c1753 1806 assert_se(isempty(p));
d6293c07
FB
1807
1808 p = original = "\\w+\\b";
68685607 1809 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE|EXTRACT_CUNESCAPE_RELAX) > 0);
d6293c07
FB
1810 assert_se(streq(t, "\\w+\b"));
1811 free(t);
4b1c1753 1812 assert_se(isempty(p));
14e685c2
RM
1813
1814 p = original = "-N ''";
12ba2c44 1815 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) > 0);
14e685c2
RM
1816 assert_se(streq(t, "-N"));
1817 free(t);
1818 assert_se(p == original + 3);
1819
12ba2c44 1820 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) > 0);
14e685c2
RM
1821 assert_se(streq(t, ""));
1822 free(t);
4b1c1753 1823 assert_se(isempty(p));
206644ae
RM
1824
1825 p = original = ":foo\\:bar::waldo:";
1826 assert_se(extract_first_word(&p, &t, ":", EXTRACT_DONT_COALESCE_SEPARATORS) == 1);
1827 assert_se(t);
1828 assert_se(streq(t, ""));
1829 free(t);
1830 assert_se(p == original + 1);
1831
1832 assert_se(extract_first_word(&p, &t, ":", EXTRACT_DONT_COALESCE_SEPARATORS) == 1);
1833 assert_se(streq(t, "foo:bar"));
1834 free(t);
1835 assert_se(p == original + 10);
1836
1837 assert_se(extract_first_word(&p, &t, ":", EXTRACT_DONT_COALESCE_SEPARATORS) == 1);
1838 assert_se(t);
1839 assert_se(streq(t, ""));
1840 free(t);
1841 assert_se(p == original + 11);
1842
1843 assert_se(extract_first_word(&p, &t, ":", EXTRACT_DONT_COALESCE_SEPARATORS) == 1);
1844 assert_se(streq(t, "waldo"));
1845 free(t);
1846 assert_se(p == original + 17);
1847
1848 assert_se(extract_first_word(&p, &t, ":", EXTRACT_DONT_COALESCE_SEPARATORS) == 1);
1849 assert_se(streq(t, ""));
1850 free(t);
1851 assert_se(p == NULL);
1852
1853 assert_se(extract_first_word(&p, &t, ":", EXTRACT_DONT_COALESCE_SEPARATORS) == 0);
1854 assert_se(!t);
1855 assert_se(!p);
7629889c
LP
1856}
1857
68685607 1858static void test_extract_first_word_and_warn(void) {
b59292b2
FB
1859 const char *p, *original;
1860 char *t;
1861
1862 p = original = "foobar waldo";
68685607 1863 assert_se(extract_first_word_and_warn(&p, &t, NULL, 0, NULL, "fake", 1, original) > 0);
b59292b2
FB
1864 assert_se(streq(t, "foobar"));
1865 free(t);
1866 assert_se(p == original + 7);
1867
68685607 1868 assert_se(extract_first_word_and_warn(&p, &t, NULL, 0, NULL, "fake", 1, original) > 0);
b59292b2
FB
1869 assert_se(streq(t, "waldo"));
1870 free(t);
4b1c1753 1871 assert_se(isempty(p));
b59292b2 1872
68685607 1873 assert_se(extract_first_word_and_warn(&p, &t, NULL, 0, NULL, "fake", 1, original) == 0);
b59292b2 1874 assert_se(!t);
4b1c1753 1875 assert_se(isempty(p));
b59292b2
FB
1876
1877 p = original = "\"foobar\" \'waldo\'";
12ba2c44 1878 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES, NULL, "fake", 1, original) > 0);
b59292b2
FB
1879 assert_se(streq(t, "foobar"));
1880 free(t);
1881 assert_se(p == original + 9);
1882
12ba2c44 1883 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES, NULL, "fake", 1, original) > 0);
b59292b2
FB
1884 assert_se(streq(t, "waldo"));
1885 free(t);
4b1c1753 1886 assert_se(isempty(p));
b59292b2 1887
68685607 1888 assert_se(extract_first_word_and_warn(&p, &t, NULL, 0, NULL, "fake", 1, original) == 0);
b59292b2 1889 assert_se(!t);
4b1c1753 1890 assert_se(isempty(p));
b59292b2
FB
1891
1892 p = original = "\"";
12ba2c44 1893 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES, NULL, "fake", 1, original) == -EINVAL);
b59292b2
FB
1894 assert_se(p == original + 1);
1895
1896 p = original = "\'";
12ba2c44 1897 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES, NULL, "fake", 1, original) == -EINVAL);
b59292b2
FB
1898 assert_se(p == original + 1);
1899
1900 p = original = "\'fooo";
12ba2c44 1901 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES, NULL, "fake", 1, original) == -EINVAL);
b59292b2
FB
1902 assert_se(p == original + 5);
1903
1904 p = original = "\'fooo";
12ba2c44 1905 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_RELAX, NULL, "fake", 1, original) > 0);
b59292b2
FB
1906 assert_se(streq(t, "fooo"));
1907 free(t);
4b1c1753 1908 assert_se(isempty(p));
b59292b2
FB
1909
1910 p = original = " foo\\ba\\x6ar ";
68685607 1911 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_CUNESCAPE, NULL, "fake", 1, original) > 0);
b59292b2
FB
1912 assert_se(streq(t, "foo\ba\x6ar"));
1913 free(t);
4b1c1753 1914 assert_se(isempty(p));
b59292b2
FB
1915
1916 p = original = " foo\\ba\\x6ar ";
68685607 1917 assert_se(extract_first_word_and_warn(&p, &t, NULL, 0, NULL, "fake", 1, original) > 0);
b59292b2
FB
1918 assert_se(streq(t, "foobax6ar"));
1919 free(t);
4b1c1753 1920 assert_se(isempty(p));
b59292b2
FB
1921
1922 p = original = " f\\u00f6o \"pi\\U0001F4A9le\" ";
68685607 1923 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_CUNESCAPE, NULL, "fake", 1, original) > 0);
b59292b2
FB
1924 assert_se(streq(t, "föo"));
1925 free(t);
1926 assert_se(p == original + 13);
1927
12ba2c44 1928 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE, NULL, "fake", 1, original) > 0);
b59292b2
FB
1929 assert_se(streq(t, "pi\360\237\222\251le"));
1930 free(t);
4b1c1753 1931 assert_se(isempty(p));
b59292b2
FB
1932
1933 p = original = "fooo\\";
68685607 1934 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_RELAX, NULL, "fake", 1, original) > 0);
b59292b2
FB
1935 assert_se(streq(t, "fooo"));
1936 free(t);
4b1c1753 1937 assert_se(isempty(p));
b59292b2
FB
1938
1939 p = original = "fooo\\";
68685607 1940 assert_se(extract_first_word_and_warn(&p, &t, NULL, 0, NULL, "fake", 1, original) > 0);
b59292b2
FB
1941 assert_se(streq(t, "fooo\\"));
1942 free(t);
4b1c1753 1943 assert_se(isempty(p));
b59292b2
FB
1944
1945 p = original = "fooo\\";
68685607 1946 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_CUNESCAPE, NULL, "fake", 1, original) > 0);
b59292b2
FB
1947 assert_se(streq(t, "fooo\\"));
1948 free(t);
4b1c1753 1949 assert_se(isempty(p));
b59292b2
FB
1950
1951 p = original = "\"foo\\";
12ba2c44 1952 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES, NULL, "fake", 1, original) == -EINVAL);
b59292b2
FB
1953 assert_se(p == original + 5);
1954
1955 p = original = "\"foo\\";
12ba2c44 1956 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_RELAX, NULL, "fake", 1, original) > 0);
b59292b2
FB
1957 assert_se(streq(t, "foo"));
1958 free(t);
4b1c1753 1959 assert_se(isempty(p));
b59292b2
FB
1960
1961 p = original = "\"foo\\";
12ba2c44 1962 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE, NULL, "fake", 1, original) == -EINVAL);
b59292b2
FB
1963 assert_se(p == original + 5);
1964
1965 p = original = "\"foo\\";
12ba2c44 1966 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE|EXTRACT_RELAX, NULL, "fake", 1, original) > 0);
b59292b2
FB
1967 assert_se(streq(t, "foo"));
1968 free(t);
4b1c1753 1969 assert_se(isempty(p));
b59292b2
FB
1970
1971 p = original = "fooo\\ bar quux";
68685607 1972 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_RELAX, NULL, "fake", 1, original) > 0);
b59292b2
FB
1973 assert_se(streq(t, "fooo bar"));
1974 free(t);
1975 assert_se(p == original + 10);
1976
1977 p = original = "fooo\\ bar quux";
68685607 1978 assert_se(extract_first_word_and_warn(&p, &t, NULL, 0, NULL, "fake", 1, original) > 0);
b59292b2
FB
1979 assert_se(streq(t, "fooo bar"));
1980 free(t);
1981 assert_se(p == original + 10);
1982
1983 p = original = "fooo\\ bar quux";
68685607 1984 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_CUNESCAPE, NULL, "fake", 1, original) > 0);
b59292b2
FB
1985 assert_se(streq(t, "fooo\\ bar"));
1986 free(t);
1987 assert_se(p == original + 10);
1988
1989 p = original = "\\w+@\\K[\\d.]+";
68685607 1990 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_CUNESCAPE, NULL, "fake", 1, original) > 0);
b59292b2
FB
1991 assert_se(streq(t, "\\w+@\\K[\\d.]+"));
1992 free(t);
4b1c1753 1993 assert_se(isempty(p));
b59292b2
FB
1994
1995 p = original = "\\w+\\b";
68685607 1996 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_CUNESCAPE, NULL, "fake", 1, original) > 0);
b59292b2
FB
1997 assert_se(streq(t, "\\w+\b"));
1998 free(t);
4b1c1753 1999 assert_se(isempty(p));
b59292b2
FB
2000}
2001
68685607 2002static void test_extract_many_words(void) {
7629889c
LP
2003 const char *p, *original;
2004 char *a, *b, *c;
2005
2006 p = original = "foobar waldi piep";
68685607 2007 assert_se(extract_many_words(&p, NULL, 0, &a, &b, &c, NULL) == 3);
4b1c1753 2008 assert_se(isempty(p));
7629889c
LP
2009 assert_se(streq_ptr(a, "foobar"));
2010 assert_se(streq_ptr(b, "waldi"));
2011 assert_se(streq_ptr(c, "piep"));
2012 free(a);
2013 free(b);
2014 free(c);
2015
2016 p = original = "'foobar' wa\"ld\"i ";
68685607 2017 assert_se(extract_many_words(&p, NULL, 0, &a, &b, &c, NULL) == 2);
4b1c1753 2018 assert_se(isempty(p));
12ba2c44
RM
2019 assert_se(streq_ptr(a, "'foobar'"));
2020 assert_se(streq_ptr(b, "wa\"ld\"i"));
2021 assert_se(streq_ptr(c, NULL));
2022 free(a);
2023 free(b);
2024
2025 p = original = "'foobar' wa\"ld\"i ";
2026 assert_se(extract_many_words(&p, NULL, EXTRACT_QUOTES, &a, &b, &c, NULL) == 2);
2027 assert_se(isempty(p));
7629889c
LP
2028 assert_se(streq_ptr(a, "foobar"));
2029 assert_se(streq_ptr(b, "waldi"));
2030 assert_se(streq_ptr(c, NULL));
2031 free(a);
2032 free(b);
2033
2034 p = original = "";
68685607 2035 assert_se(extract_many_words(&p, NULL, 0, &a, &b, &c, NULL) == 0);
4b1c1753 2036 assert_se(isempty(p));
7629889c
LP
2037 assert_se(streq_ptr(a, NULL));
2038 assert_se(streq_ptr(b, NULL));
2039 assert_se(streq_ptr(c, NULL));
2040
2041 p = original = " ";
68685607 2042 assert_se(extract_many_words(&p, NULL, 0, &a, &b, &c, NULL) == 0);
4b1c1753 2043 assert_se(isempty(p));
7629889c
LP
2044 assert_se(streq_ptr(a, NULL));
2045 assert_se(streq_ptr(b, NULL));
2046 assert_se(streq_ptr(c, NULL));
2047
2048 p = original = "foobar";
68685607 2049 assert_se(extract_many_words(&p, NULL, 0, NULL) == 0);
7629889c
LP
2050 assert_se(p == original);
2051
2052 p = original = "foobar waldi";
68685607 2053 assert_se(extract_many_words(&p, NULL, 0, &a, NULL) == 1);
7629889c
LP
2054 assert_se(p == original+7);
2055 assert_se(streq_ptr(a, "foobar"));
eee84633 2056 free(a);
7629889c
LP
2057
2058 p = original = " foobar ";
68685607 2059 assert_se(extract_many_words(&p, NULL, 0, &a, NULL) == 1);
4b1c1753 2060 assert_se(isempty(p));
7629889c 2061 assert_se(streq_ptr(a, "foobar"));
eee84633 2062 free(a);
7629889c
LP
2063}
2064
f32d2db1
LP
2065static int parse_item(const char *key, const char *value) {
2066 assert_se(key);
2067
2068 log_info("kernel cmdline option <%s> = <%s>", key, strna(value));
2069 return 0;
2070}
2071
2072static void test_parse_proc_cmdline(void) {
2073 assert_se(parse_proc_cmdline(parse_item) >= 0);
2074}
2075
ee05e779
ZJS
2076static void test_raw_clone(void) {
2077 pid_t parent, pid, pid2;
2078
2079 parent = getpid();
2080 log_info("before clone: getpid()→"PID_FMT, parent);
2081 assert_se(raw_getpid() == parent);
2082
2083 pid = raw_clone(0, NULL);
e50221bf 2084 assert_se(pid >= 0);
ee05e779
ZJS
2085
2086 pid2 = raw_getpid();
2087 log_info("raw_clone: "PID_FMT" getpid()→"PID_FMT" raw_getpid()→"PID_FMT,
2088 pid, getpid(), pid2);
0289a5bc 2089 if (pid == 0) {
e50221bf 2090 assert_se(pid2 != parent);
0289a5bc
FB
2091 _exit(EXIT_SUCCESS);
2092 } else {
2093 int status;
2094
e50221bf 2095 assert_se(pid2 == parent);
0289a5bc
FB
2096 waitpid(pid, &status, __WCLONE);
2097 assert_se(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS);
2098 }
ee05e779
ZJS
2099}
2100
f7ad54a3
LP
2101static void test_same_fd(void) {
2102 _cleanup_close_pair_ int p[2] = { -1, -1 };
2103 _cleanup_close_ int a = -1, b = -1, c = -1;
2104
2105 assert_se(pipe2(p, O_CLOEXEC) >= 0);
2106 assert_se((a = dup(p[0])) >= 0);
2107 assert_se((b = open("/dev/null", O_RDONLY|O_CLOEXEC)) >= 0);
2108 assert_se((c = dup(a)) >= 0);
2109
2110 assert_se(same_fd(p[0], p[0]) > 0);
2111 assert_se(same_fd(p[1], p[1]) > 0);
2112 assert_se(same_fd(a, a) > 0);
2113 assert_se(same_fd(b, b) > 0);
2114
2115 assert_se(same_fd(a, p[0]) > 0);
2116 assert_se(same_fd(p[0], a) > 0);
2117 assert_se(same_fd(c, p[0]) > 0);
2118 assert_se(same_fd(p[0], c) > 0);
2119 assert_se(same_fd(a, c) > 0);
2120 assert_se(same_fd(c, a) > 0);
2121
2122 assert_se(same_fd(p[0], p[1]) == 0);
2123 assert_se(same_fd(p[1], p[0]) == 0);
2124 assert_se(same_fd(p[0], b) == 0);
2125 assert_se(same_fd(b, p[0]) == 0);
2126 assert_se(same_fd(p[1], a) == 0);
2127 assert_se(same_fd(a, p[1]) == 0);
2128 assert_se(same_fd(p[1], b) == 0);
2129 assert_se(same_fd(b, p[1]) == 0);
2130
2131 assert_se(same_fd(a, b) == 0);
2132 assert_se(same_fd(b, a) == 0);
2133}
2134
8cb4ab00
LP
2135static void test_uid_ptr(void) {
2136
2137 assert_se(UID_TO_PTR(0) != NULL);
2138 assert_se(UID_TO_PTR(1000) != NULL);
2139
2140 assert_se(PTR_TO_UID(UID_TO_PTR(0)) == 0);
2141 assert_se(PTR_TO_UID(UID_TO_PTR(1000)) == 1000);
2142}
2143
ff6a7460
LP
2144static void test_sparse_write_one(int fd, const char *buffer, size_t n) {
2145 char check[n];
2146
2147 assert_se(lseek(fd, 0, SEEK_SET) == 0);
2148 assert_se(ftruncate(fd, 0) >= 0);
2149 assert_se(sparse_write(fd, buffer, n, 4) == (ssize_t) n);
2150
2151 assert_se(lseek(fd, 0, SEEK_CUR) == (off_t) n);
2152 assert_se(ftruncate(fd, n) >= 0);
2153
2154 assert_se(lseek(fd, 0, SEEK_SET) == 0);
2155 assert_se(read(fd, check, n) == (ssize_t) n);
2156
2157 assert_se(memcmp(buffer, check, n) == 0);
2158}
2159
2160static void test_sparse_write(void) {
2161 const char test_a[] = "test";
2162 const char test_b[] = "\0\0\0\0test\0\0\0\0";
2163 const char test_c[] = "\0\0test\0\0\0\0";
2164 const char test_d[] = "\0\0test\0\0\0test\0\0\0\0test\0\0\0\0\0test\0\0\0test\0\0\0\0test\0\0\0\0\0\0\0\0";
2165 const char test_e[] = "test\0\0\0\0test";
2166 _cleanup_close_ int fd = -1;
2167 char fn[] = "/tmp/sparseXXXXXX";
2168
2169 fd = mkostemp(fn, O_CLOEXEC);
2170 assert_se(fd >= 0);
2171 unlink(fn);
2172
2173 test_sparse_write_one(fd, test_a, sizeof(test_a));
2174 test_sparse_write_one(fd, test_b, sizeof(test_b));
2175 test_sparse_write_one(fd, test_c, sizeof(test_c));
2176 test_sparse_write_one(fd, test_d, sizeof(test_d));
2177 test_sparse_write_one(fd, test_e, sizeof(test_e));
2178}
2179
61ee6939
RM
2180static void test_shell_escape_one(const char *s, const char *bad, const char *expected) {
2181 _cleanup_free_ char *r;
2182
2183 assert_se(r = shell_escape(s, bad));
2184 assert_se(streq_ptr(r, expected));
2185}
2186
2187static void test_shell_escape(void) {
2188 test_shell_escape_one("", "", "");
2189 test_shell_escape_one("\\", "", "\\\\");
2190 test_shell_escape_one("foobar", "", "foobar");
2191 test_shell_escape_one("foobar", "o", "f\\o\\obar");
2192 test_shell_escape_one("foo:bar,baz", ",:", "foo\\:bar\\,baz");
2193}
2194
019c7fba
LP
2195static void test_shell_maybe_quote_one(const char *s, const char *expected) {
2196 _cleanup_free_ char *r;
2197
2198 assert_se(r = shell_maybe_quote(s));
2199 assert_se(streq(r, expected));
2200}
2201
2202static void test_shell_maybe_quote(void) {
2203
2204 test_shell_maybe_quote_one("", "");
2205 test_shell_maybe_quote_one("\\", "\"\\\\\"");
2206 test_shell_maybe_quote_one("\"", "\"\\\"\"");
2207 test_shell_maybe_quote_one("foobar", "foobar");
2208 test_shell_maybe_quote_one("foo bar", "\"foo bar\"");
2209 test_shell_maybe_quote_one("foo \"bar\" waldo", "\"foo \\\"bar\\\" waldo\"");
2210 test_shell_maybe_quote_one("foo$bar", "\"foo\\$bar\"");
2211}
2212
2ff7b0a5
LP
2213static void test_parse_mode(void) {
2214 mode_t m;
2215
2216 assert_se(parse_mode("-1", &m) < 0);
2217 assert_se(parse_mode("", &m) < 0);
2218 assert_se(parse_mode("888", &m) < 0);
2219 assert_se(parse_mode("77777", &m) < 0);
2220
2221 assert_se(parse_mode("544", &m) >= 0 && m == 0544);
2222 assert_se(parse_mode("777", &m) >= 0 && m == 0777);
2223 assert_se(parse_mode("7777", &m) >= 0 && m == 07777);
2224 assert_se(parse_mode("0", &m) >= 0 && m == 0);
2225}
2226
14bcf25c
LP
2227static void test_tempfn(void) {
2228 char *ret = NULL, *p;
2229
2230 assert_se(tempfn_xxxxxx("/foo/bar/waldo", NULL, &ret) >= 0);
2231 assert_se(streq_ptr(ret, "/foo/bar/.#waldoXXXXXX"));
2232 free(ret);
2233
2234 assert_se(tempfn_xxxxxx("/foo/bar/waldo", "[miau]", &ret) >= 0);
2235 assert_se(streq_ptr(ret, "/foo/bar/.#[miau]waldoXXXXXX"));
2236 free(ret);
2237
2238 assert_se(tempfn_random("/foo/bar/waldo", NULL, &ret) >= 0);
2239 assert_se(p = startswith(ret, "/foo/bar/.#waldo"));
2240 assert_se(strlen(p) == 16);
2241 assert_se(in_charset(p, "0123456789abcdef"));
2242 free(ret);
2243
2244 assert_se(tempfn_random("/foo/bar/waldo", "[wuff]", &ret) >= 0);
2245 assert_se(p = startswith(ret, "/foo/bar/.#[wuff]waldo"));
2246 assert_se(strlen(p) == 16);
2247 assert_se(in_charset(p, "0123456789abcdef"));
2248 free(ret);
2249
2250 assert_se(tempfn_random_child("/foo/bar/waldo", NULL, &ret) >= 0);
2251 assert_se(p = startswith(ret, "/foo/bar/waldo/.#"));
2252 assert_se(strlen(p) == 16);
2253 assert_se(in_charset(p, "0123456789abcdef"));
2254 free(ret);
2255
2256 assert_se(tempfn_random_child("/foo/bar/waldo", "[kikiriki]", &ret) >= 0);
2257 assert_se(p = startswith(ret, "/foo/bar/waldo/.#[kikiriki]"));
2258 assert_se(strlen(p) == 16);
2259 assert_se(in_charset(p, "0123456789abcdef"));
2260 free(ret);
2261}
2262
c030a850
NK
2263static void test_strcmp_ptr(void) {
2264 assert_se(strcmp_ptr(NULL, NULL) == 0);
2265 assert_se(strcmp_ptr("", NULL) > 0);
2266 assert_se(strcmp_ptr("foo", NULL) > 0);
2267 assert_se(strcmp_ptr(NULL, "") < 0);
2268 assert_se(strcmp_ptr(NULL, "bar") < 0);
2269 assert_se(strcmp_ptr("foo", "bar") > 0);
2270 assert_se(strcmp_ptr("bar", "baz") < 0);
2271 assert_se(strcmp_ptr("foo", "foo") == 0);
2272 assert_se(strcmp_ptr("", "") == 0);
2273}
2274
df241a67
LP
2275static void test_fgetxattrat_fake(void) {
2276 char t[] = "/var/tmp/xattrtestXXXXXX";
2277 _cleanup_close_ int fd = -1;
2278 const char *x;
2279 char v[3] = {};
2280 int r;
2281
2282 assert_se(mkdtemp(t));
2283 x = strjoina(t, "/test");
2284 assert_se(touch(x) >= 0);
2285
2286 r = setxattr(x, "user.foo", "bar", 3, 0);
2287 if (r < 0 && errno == EOPNOTSUPP) /* no xattrs supported on /var/tmp... */
2288 goto cleanup;
2289 assert_se(r >= 0);
2290
2291 fd = open(t, O_RDONLY|O_DIRECTORY|O_CLOEXEC|O_NOCTTY);
2292 assert_se(fd >= 0);
2293
2294 assert_se(fgetxattrat_fake(fd, "test", "user.foo", v, 3, 0) >= 0);
2295 assert_se(memcmp(v, "bar", 3) == 0);
2296
2297 safe_close(fd);
2298 fd = open("/", O_RDONLY|O_DIRECTORY|O_CLOEXEC|O_NOCTTY);
2299 assert_se(fd >= 0);
2300 assert_se(fgetxattrat_fake(fd, "usr", "user.idontexist", v, 3, 0) == -ENODATA);
2301
2302cleanup:
2303 assert_se(unlink(x) >= 0);
2304 assert_se(rmdir(t) >= 0);
2305}
2306
539ad707 2307int main(int argc, char *argv[]) {
9480794b
ZJS
2308 log_parse_environment();
2309 log_open();
2310
539ad707 2311 test_streq_ptr();
625e870b 2312 test_align_power2();
7242d742 2313 test_max();
fb835651 2314 test_container_of();
95d78c7e 2315 test_alloca();
180a60bc 2316 test_div_round_up();
539ad707 2317 test_first_word();
dbd73f9e 2318 test_close_many();
8354c34e 2319 test_parse_boolean();
8d99e5f5
TA
2320 test_parse_pid();
2321 test_parse_uid();
ff9265d0
DM
2322 test_safe_atou16();
2323 test_safe_atoi16();
8d99e5f5
TA
2324 test_safe_atolli();
2325 test_safe_atod();
dbd73f9e 2326 test_strappend();
1ef04f0b
TA
2327 test_strstrip();
2328 test_delete_chars();
2329 test_in_charset();
44f4c86c
DB
2330 test_hexchar();
2331 test_unhexchar();
919a7f5f
TG
2332 test_base32hexchar();
2333 test_unbase32hexchar();
13a5d76b
TG
2334 test_base64char();
2335 test_unbase64char();
44f4c86c
DB
2336 test_octchar();
2337 test_unoctchar();
2338 test_decchar();
2339 test_undecchar();
30494563 2340 test_unhexmem();
919a7f5f
TG
2341 test_base32hexmem();
2342 test_unbase32hexmem();
13a5d76b
TG
2343 test_base64mem();
2344 test_unbase64mem();
b4ecc959
TA
2345 test_cescape();
2346 test_cunescape();
1ef04f0b 2347 test_foreach_word();
539ad707 2348 test_foreach_word_quoted();
0d585d82 2349 test_memdup_multiply();
144e51ec 2350 test_u64log2();
2a371001 2351 test_protect_errno();
5556b5fe 2352 test_parse_size();
5f05235f 2353 test_parse_cpu_set();
59f448cf 2354 test_config_parse_iec_uint64();
b4ecc959
TA
2355 test_strextend();
2356 test_strrep();
d4ac85c6 2357 test_split_pair();
22f5f628 2358 test_fstab_node_to_udev_node();
893fa014 2359 test_get_files_in_directory();
cabb7806 2360 test_in_set();
87b02843 2361 test_writing_tmpfile();
29bfbcd6 2362 test_hexdump();
8fe90522 2363 test_log2i();
c4a7b2c5 2364 test_foreach_string();
ae6c3cc0 2365 test_filename_is_valid();
1cb1767a 2366 test_string_has_cc();
927be00c
RC
2367 test_ascii_strlower();
2368 test_files_same();
2369 test_is_valid_documentation_url();
2370 test_file_in_same_dir();
2371 test_endswith();
ff9265d0 2372 test_endswith_no_case();
927be00c
RC
2373 test_close_nointr();
2374 test_unlink_noerrno();
2375 test_readlink_and_make_absolute();
927be00c
RC
2376 test_ignore_signals();
2377 test_strshorten();
63c372cb 2378 test_strjoina();
8852362b 2379 test_is_symlink();
8852362b
RC
2380 test_search_and_fopen();
2381 test_search_and_fopen_nulstr();
2382 test_glob_exists();
2383 test_execute_directory();
68685607
RM
2384 test_extract_first_word();
2385 test_extract_first_word_and_warn();
2386 test_extract_many_words();
f32d2db1 2387 test_parse_proc_cmdline();
ee05e779 2388 test_raw_clone();
f7ad54a3 2389 test_same_fd();
8cb4ab00 2390 test_uid_ptr();
ff6a7460 2391 test_sparse_write();
61ee6939 2392 test_shell_escape();
019c7fba 2393 test_shell_maybe_quote();
2ff7b0a5 2394 test_parse_mode();
14bcf25c 2395 test_tempfn();
c030a850 2396 test_strcmp_ptr();
df241a67 2397 test_fgetxattrat_fake();
539ad707
TA
2398
2399 return 0;
2400}