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