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