]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/test/test-string-util.c
Merge pull request #7530 from poettering/uid-gid-fixes
[thirdparty/systemd.git] / src / test / test-string-util.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
9fe4ea21
LP
2/***
3 This file is part of systemd.
4
5 Copyright 2015 Lennart Poettering
6
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
11
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
19***/
20
6571a64e
RC
21#include "alloc-util.h"
22#include "macro.h"
9fe4ea21 23#include "string-util.h"
6571a64e 24#include "strv.h"
9fe4ea21
LP
25
26static void test_string_erase(void) {
27 char *x;
28
29 x = strdupa("");
30 assert_se(streq(string_erase(x), ""));
31
32 x = strdupa("1");
2d26d8e0 33 assert_se(streq(string_erase(x), ""));
9fe4ea21
LP
34
35 x = strdupa("123456789");
2d26d8e0
ZJS
36 assert_se(streq(string_erase(x), ""));
37
38 assert_se(x[1] == '\0');
39 assert_se(x[2] == '\0');
40 assert_se(x[3] == '\0');
41 assert_se(x[4] == '\0');
42 assert_se(x[5] == '\0');
43 assert_se(x[6] == '\0');
44 assert_se(x[7] == '\0');
45 assert_se(x[8] == '\0');
46 assert_se(x[9] == '\0');
9fe4ea21
LP
47}
48
522d85ae
LP
49static void test_ascii_strcasecmp_n(void) {
50
51 assert_se(ascii_strcasecmp_n("", "", 0) == 0);
52 assert_se(ascii_strcasecmp_n("", "", 1) == 0);
53 assert_se(ascii_strcasecmp_n("", "a", 1) < 0);
54 assert_se(ascii_strcasecmp_n("", "a", 2) < 0);
55 assert_se(ascii_strcasecmp_n("a", "", 1) > 0);
56 assert_se(ascii_strcasecmp_n("a", "", 2) > 0);
57 assert_se(ascii_strcasecmp_n("a", "a", 1) == 0);
58 assert_se(ascii_strcasecmp_n("a", "a", 2) == 0);
59 assert_se(ascii_strcasecmp_n("a", "b", 1) < 0);
60 assert_se(ascii_strcasecmp_n("a", "b", 2) < 0);
61 assert_se(ascii_strcasecmp_n("b", "a", 1) > 0);
62 assert_se(ascii_strcasecmp_n("b", "a", 2) > 0);
63 assert_se(ascii_strcasecmp_n("xxxxyxxxx", "xxxxYxxxx", 9) == 0);
64 assert_se(ascii_strcasecmp_n("xxxxxxxxx", "xxxxyxxxx", 9) < 0);
65 assert_se(ascii_strcasecmp_n("xxxxXxxxx", "xxxxyxxxx", 9) < 0);
66 assert_se(ascii_strcasecmp_n("xxxxxxxxx", "xxxxYxxxx", 9) < 0);
67 assert_se(ascii_strcasecmp_n("xxxxXxxxx", "xxxxYxxxx", 9) < 0);
68
69 assert_se(ascii_strcasecmp_n("xxxxYxxxx", "xxxxYxxxx", 9) == 0);
70 assert_se(ascii_strcasecmp_n("xxxxyxxxx", "xxxxxxxxx", 9) > 0);
71 assert_se(ascii_strcasecmp_n("xxxxyxxxx", "xxxxXxxxx", 9) > 0);
72 assert_se(ascii_strcasecmp_n("xxxxYxxxx", "xxxxxxxxx", 9) > 0);
73 assert_se(ascii_strcasecmp_n("xxxxYxxxx", "xxxxXxxxx", 9) > 0);
74}
75
c1749834
LP
76static void test_ascii_strcasecmp_nn(void) {
77 assert_se(ascii_strcasecmp_nn("", 0, "", 0) == 0);
78 assert_se(ascii_strcasecmp_nn("", 0, "", 1) < 0);
79 assert_se(ascii_strcasecmp_nn("", 1, "", 0) > 0);
80 assert_se(ascii_strcasecmp_nn("", 1, "", 1) == 0);
81
82 assert_se(ascii_strcasecmp_nn("aaaa", 4, "aaAa", 4) == 0);
83 assert_se(ascii_strcasecmp_nn("aaa", 3, "aaAa", 4) < 0);
84 assert_se(ascii_strcasecmp_nn("aaa", 4, "aaAa", 4) < 0);
85 assert_se(ascii_strcasecmp_nn("aaaa", 4, "aaA", 3) > 0);
86 assert_se(ascii_strcasecmp_nn("aaaa", 4, "AAA", 4) > 0);
87
88 assert_se(ascii_strcasecmp_nn("aaaa", 4, "bbbb", 4) < 0);
89 assert_se(ascii_strcasecmp_nn("aaAA", 4, "BBbb", 4) < 0);
90 assert_se(ascii_strcasecmp_nn("BBbb", 4, "aaaa", 4) > 0);
91}
92
6571a64e
RC
93static void test_streq_ptr(void) {
94 assert_se(streq_ptr(NULL, NULL));
95 assert_se(!streq_ptr("abc", "cdef"));
96}
97
98static void test_strstrip(void) {
99 char *r;
100 char input[] = " hello, waldo. ";
101
102 r = strstrip(input);
103 assert_se(streq(r, "hello, waldo."));
104}
105
106static void test_strextend(void) {
bb8ad9ea
LP
107 _cleanup_free_ char *str = NULL;
108
109 assert_se(strextend(&str, NULL));
110 assert_se(streq_ptr(str, ""));
111 assert_se(strextend(&str, "", "0", "", "", "123", NULL));
112 assert_se(streq_ptr(str, "0123"));
113 assert_se(strextend(&str, "456", "78", "9", NULL));
114 assert_se(streq_ptr(str, "0123456789"));
115}
116
117static void test_strextend_with_separator(void) {
118 _cleanup_free_ char *str = NULL;
119
120 assert_se(strextend_with_separator(&str, NULL, NULL));
121 assert_se(streq_ptr(str, ""));
122 str = mfree(str);
123
124 assert_se(strextend_with_separator(&str, "...", NULL));
125 assert_se(streq_ptr(str, ""));
126 assert_se(strextend_with_separator(&str, "...", NULL));
127 assert_se(streq_ptr(str, ""));
128 str = mfree(str);
129
130 assert_se(strextend_with_separator(&str, "xyz", "a", "bb", "ccc", NULL));
131 assert_se(streq_ptr(str, "axyzbbxyzccc"));
132 str = mfree(str);
133
134 assert_se(strextend_with_separator(&str, ",", "start", "", "1", "234", NULL));
135 assert_se(streq_ptr(str, "start,,1,234"));
136 assert_se(strextend_with_separator(&str, ";", "more", "5", "678", NULL));
137 assert_se(streq_ptr(str, "start,,1,234;more;5;678"));
6571a64e
RC
138}
139
140static void test_strrep(void) {
141 _cleanup_free_ char *one, *three, *zero;
142 one = strrep("waldo", 1);
143 three = strrep("waldo", 3);
144 zero = strrep("waldo", 0);
145
146 assert_se(streq(one, "waldo"));
147 assert_se(streq(three, "waldowaldowaldo"));
148 assert_se(streq(zero, ""));
149}
150
151
152static void test_strappend(void) {
153 _cleanup_free_ char *t1, *t2, *t3, *t4;
154
155 t1 = strappend(NULL, NULL);
156 assert_se(streq(t1, ""));
157
158 t2 = strappend(NULL, "suf");
159 assert_se(streq(t2, "suf"));
160
161 t3 = strappend("pre", NULL);
162 assert_se(streq(t3, "pre"));
163
164 t4 = strappend("pre", "suf");
165 assert_se(streq(t4, "presuf"));
166}
167
168static void test_string_has_cc(void) {
169 assert_se(string_has_cc("abc\1", NULL));
170 assert_se(string_has_cc("abc\x7f", NULL));
171 assert_se(string_has_cc("abc\x7f", NULL));
172 assert_se(string_has_cc("abc\t\x7f", "\t"));
173 assert_se(string_has_cc("abc\t\x7f", "\t"));
174 assert_se(string_has_cc("\x7f", "\t"));
175 assert_se(string_has_cc("\x7f", "\t\a"));
176
177 assert_se(!string_has_cc("abc\t\t", "\t"));
178 assert_se(!string_has_cc("abc\t\t\a", "\t\a"));
179 assert_se(!string_has_cc("a\ab\tc", "\t\a"));
180}
181
182static void test_ascii_strlower(void) {
183 char a[] = "AabBcC Jk Ii Od LKJJJ kkd LK";
184 assert_se(streq(ascii_strlower(a), "aabbcc jk ii od lkjjj kkd lk"));
185}
186
187static void test_strshorten(void) {
188 char s[] = "foobar";
189
190 assert_se(strlen(strshorten(s, 6)) == 6);
191 assert_se(strlen(strshorten(s, 12)) == 6);
192 assert_se(strlen(strshorten(s, 2)) == 2);
193 assert_se(strlen(strshorten(s, 0)) == 0);
194}
195
196static void test_strjoina(void) {
197 char *actual;
198
199 actual = strjoina("", "foo", "bar");
200 assert_se(streq(actual, "foobar"));
201
202 actual = strjoina("foo", "bar", "baz");
203 assert_se(streq(actual, "foobarbaz"));
204
205 actual = strjoina("foo", "", "bar", "baz");
206 assert_se(streq(actual, "foobarbaz"));
207
208 actual = strjoina("foo");
209 assert_se(streq(actual, "foo"));
210
211 actual = strjoina(NULL);
212 assert_se(streq(actual, ""));
213
214 actual = strjoina(NULL, "foo");
215 assert_se(streq(actual, ""));
216
217 actual = strjoina("foo", NULL, "bar");
218 assert_se(streq(actual, "foo"));
219}
220
221static void test_strcmp_ptr(void) {
222 assert_se(strcmp_ptr(NULL, NULL) == 0);
223 assert_se(strcmp_ptr("", NULL) > 0);
224 assert_se(strcmp_ptr("foo", NULL) > 0);
225 assert_se(strcmp_ptr(NULL, "") < 0);
226 assert_se(strcmp_ptr(NULL, "bar") < 0);
227 assert_se(strcmp_ptr("foo", "bar") > 0);
228 assert_se(strcmp_ptr("bar", "baz") < 0);
229 assert_se(strcmp_ptr("foo", "foo") == 0);
230 assert_se(strcmp_ptr("", "") == 0);
231}
232
233static void test_foreach_word(void) {
234 const char *word, *state;
235 size_t l;
236 int i = 0;
237 const char test[] = "test abc d\te f ";
238 const char * const expected[] = {
239 "test",
240 "abc",
241 "d",
242 "e",
243 "f",
244 "",
245 NULL
246 };
247
248 FOREACH_WORD(word, l, test, state)
249 assert_se(strneq(expected[i++], word, l));
250}
251
252static void check(const char *test, char** expected, bool trailing) {
bc8ec170 253 int i = 0, r;
6571a64e
RC
254
255 printf("<<<%s>>>\n", test);
bc8ec170
ZJS
256 for (;;) {
257 _cleanup_free_ char *word = NULL;
258
259 r = extract_first_word(&test, &word, NULL, EXTRACT_QUOTES);
260 if (r == 0) {
261 assert_se(!trailing);
262 break;
263 } else if (r < 0) {
264 assert_se(trailing);
265 break;
266 }
267
268 assert_se(streq(word, expected[i++]));
269 printf("<%s>\n", word);
6571a64e 270 }
6571a64e 271 assert_se(expected[i] == NULL);
6571a64e
RC
272}
273
274static void test_foreach_word_quoted(void) {
275 check("test a b c 'd' e '' '' hhh '' '' \"a b c\"",
276 STRV_MAKE("test",
277 "a",
278 "b",
279 "c",
280 "d",
281 "e",
282 "",
283 "",
284 "hhh",
285 "",
286 "",
287 "a b c"),
288 false);
289
290 check("test \"xxx",
291 STRV_MAKE("test"),
292 true);
293
294 check("test\\",
295 STRV_MAKE_EMPTY,
296 true);
297}
298
299static void test_endswith(void) {
300 assert_se(endswith("foobar", "bar"));
301 assert_se(endswith("foobar", ""));
302 assert_se(endswith("foobar", "foobar"));
303 assert_se(endswith("", ""));
304
305 assert_se(!endswith("foobar", "foo"));
306 assert_se(!endswith("foobar", "foobarfoofoo"));
307}
308
309static void test_endswith_no_case(void) {
310 assert_se(endswith_no_case("fooBAR", "bar"));
311 assert_se(endswith_no_case("foobar", ""));
312 assert_se(endswith_no_case("foobar", "FOOBAR"));
313 assert_se(endswith_no_case("", ""));
314
315 assert_se(!endswith_no_case("foobar", "FOO"));
316 assert_se(!endswith_no_case("foobar", "FOOBARFOOFOO"));
317}
318
319static void test_delete_chars(void) {
7546145e
LP
320 char *s, input[] = " hello, waldo. abc";
321
322 s = delete_chars(input, WHITESPACE);
323 assert_se(streq(s, "hello,waldo.abc"));
324 assert_se(s == input);
325}
326
327static void test_delete_trailing_chars(void) {
328
329 char *s,
330 input1[] = " \n \r k \n \r ",
331 input2[] = "kkkkthiskkkiskkkaktestkkk",
332 input3[] = "abcdef";
333
334 s = delete_trailing_chars(input1, WHITESPACE);
335 assert_se(streq(s, " \n \r k"));
336 assert_se(s == input1);
337
338 s = delete_trailing_chars(input2, "kt");
339 assert_se(streq(s, "kkkkthiskkkiskkkaktes"));
340 assert_se(s == input2);
341
342 s = delete_trailing_chars(input3, WHITESPACE);
343 assert_se(streq(s, "abcdef"));
344 assert_se(s == input3);
345
346 s = delete_trailing_chars(input3, "fe");
347 assert_se(streq(s, "abcd"));
348 assert_se(s == input3);
349}
350
ca4d708d
ZJS
351static void test_delete_trailing_slashes(void) {
352 char s1[] = "foobar//",
353 s2[] = "foobar/",
354 s3[] = "foobar",
355 s4[] = "";
356
357 assert_se(streq(delete_trailing_chars(s1, "_"), "foobar//"));
358 assert_se(streq(delete_trailing_chars(s1, "/"), "foobar"));
359 assert_se(streq(delete_trailing_chars(s2, "/"), "foobar"));
360 assert_se(streq(delete_trailing_chars(s3, "/"), "foobar"));
361 assert_se(streq(delete_trailing_chars(s4, "/"), ""));
362}
363
7546145e
LP
364static void test_skip_leading_chars(void) {
365 char input1[] = " \n \r k \n \r ",
366 input2[] = "kkkkthiskkkiskkkaktestkkk",
367 input3[] = "abcdef";
6571a64e 368
7546145e
LP
369 assert_se(streq(skip_leading_chars(input1, WHITESPACE), "k \n \r "));
370 assert_se(streq(skip_leading_chars(input2, "k"), "thiskkkiskkkaktestkkk"));
371 assert_se(streq(skip_leading_chars(input2, "tk"), "hiskkkiskkkaktestkkk"));
372 assert_se(streq(skip_leading_chars(input3, WHITESPACE), "abcdef"));
373 assert_se(streq(skip_leading_chars(input3, "bcaef"), "def"));
6571a64e
RC
374}
375
376static void test_in_charset(void) {
377 assert_se(in_charset("dddaaabbbcccc", "abcd"));
378 assert_se(!in_charset("dddaaabbbcccc", "abc f"));
379}
380
381static void test_split_pair(void) {
382 _cleanup_free_ char *a = NULL, *b = NULL;
383
384 assert_se(split_pair("", "", &a, &b) == -EINVAL);
385 assert_se(split_pair("foo=bar", "", &a, &b) == -EINVAL);
386 assert_se(split_pair("", "=", &a, &b) == -EINVAL);
387 assert_se(split_pair("foo=bar", "=", &a, &b) >= 0);
388 assert_se(streq(a, "foo"));
389 assert_se(streq(b, "bar"));
390 free(a);
391 free(b);
392 assert_se(split_pair("==", "==", &a, &b) >= 0);
393 assert_se(streq(a, ""));
394 assert_se(streq(b, ""));
395 free(a);
396 free(b);
397
398 assert_se(split_pair("===", "==", &a, &b) >= 0);
399 assert_se(streq(a, ""));
400 assert_se(streq(b, "="));
401}
402
403static void test_first_word(void) {
404 assert_se(first_word("Hello", ""));
405 assert_se(first_word("Hello", "Hello"));
406 assert_se(first_word("Hello world", "Hello"));
407 assert_se(first_word("Hello\tworld", "Hello"));
408 assert_se(first_word("Hello\nworld", "Hello"));
409 assert_se(first_word("Hello\rworld", "Hello"));
410 assert_se(first_word("Hello ", "Hello"));
411
412 assert_se(!first_word("Hello", "Hellooo"));
413 assert_se(!first_word("Hello", "xxxxx"));
414 assert_se(!first_word("Hellooo", "Hello"));
415}
416
7bf7ce28
LP
417static void test_strlen_ptr(void) {
418 assert_se(strlen_ptr("foo") == 3);
419 assert_se(strlen_ptr("") == 0);
420 assert_se(strlen_ptr(NULL) == 0);
421}
422
9fe4ea21
LP
423int main(int argc, char *argv[]) {
424 test_string_erase();
522d85ae 425 test_ascii_strcasecmp_n();
c1749834 426 test_ascii_strcasecmp_nn();
6571a64e
RC
427 test_streq_ptr();
428 test_strstrip();
429 test_strextend();
bb8ad9ea 430 test_strextend_with_separator();
6571a64e
RC
431 test_strrep();
432 test_strappend();
433 test_string_has_cc();
434 test_ascii_strlower();
435 test_strshorten();
436 test_strjoina();
437 test_strcmp_ptr();
438 test_foreach_word();
439 test_foreach_word_quoted();
440 test_endswith();
441 test_endswith_no_case();
442 test_delete_chars();
7546145e 443 test_delete_trailing_chars();
ca4d708d 444 test_delete_trailing_slashes();
7546145e 445 test_skip_leading_chars();
6571a64e
RC
446 test_in_charset();
447 test_split_pair();
448 test_first_word();
7bf7ce28 449 test_strlen_ptr();
6571a64e 450
9fe4ea21
LP
451 return 0;
452}