]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/test/test-string-util.c
test-string-util: add another test for stripping slashes
[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) {
107 _cleanup_free_ char *str = strdup("0123");
108 strextend(&str, "456", "78", "9", NULL);
109 assert_se(streq(str, "0123456789"));
110}
111
112static void test_strrep(void) {
113 _cleanup_free_ char *one, *three, *zero;
114 one = strrep("waldo", 1);
115 three = strrep("waldo", 3);
116 zero = strrep("waldo", 0);
117
118 assert_se(streq(one, "waldo"));
119 assert_se(streq(three, "waldowaldowaldo"));
120 assert_se(streq(zero, ""));
121}
122
123
124static void test_strappend(void) {
125 _cleanup_free_ char *t1, *t2, *t3, *t4;
126
127 t1 = strappend(NULL, NULL);
128 assert_se(streq(t1, ""));
129
130 t2 = strappend(NULL, "suf");
131 assert_se(streq(t2, "suf"));
132
133 t3 = strappend("pre", NULL);
134 assert_se(streq(t3, "pre"));
135
136 t4 = strappend("pre", "suf");
137 assert_se(streq(t4, "presuf"));
138}
139
140static void test_string_has_cc(void) {
141 assert_se(string_has_cc("abc\1", NULL));
142 assert_se(string_has_cc("abc\x7f", NULL));
143 assert_se(string_has_cc("abc\x7f", NULL));
144 assert_se(string_has_cc("abc\t\x7f", "\t"));
145 assert_se(string_has_cc("abc\t\x7f", "\t"));
146 assert_se(string_has_cc("\x7f", "\t"));
147 assert_se(string_has_cc("\x7f", "\t\a"));
148
149 assert_se(!string_has_cc("abc\t\t", "\t"));
150 assert_se(!string_has_cc("abc\t\t\a", "\t\a"));
151 assert_se(!string_has_cc("a\ab\tc", "\t\a"));
152}
153
154static void test_ascii_strlower(void) {
155 char a[] = "AabBcC Jk Ii Od LKJJJ kkd LK";
156 assert_se(streq(ascii_strlower(a), "aabbcc jk ii od lkjjj kkd lk"));
157}
158
159static void test_strshorten(void) {
160 char s[] = "foobar";
161
162 assert_se(strlen(strshorten(s, 6)) == 6);
163 assert_se(strlen(strshorten(s, 12)) == 6);
164 assert_se(strlen(strshorten(s, 2)) == 2);
165 assert_se(strlen(strshorten(s, 0)) == 0);
166}
167
168static void test_strjoina(void) {
169 char *actual;
170
171 actual = strjoina("", "foo", "bar");
172 assert_se(streq(actual, "foobar"));
173
174 actual = strjoina("foo", "bar", "baz");
175 assert_se(streq(actual, "foobarbaz"));
176
177 actual = strjoina("foo", "", "bar", "baz");
178 assert_se(streq(actual, "foobarbaz"));
179
180 actual = strjoina("foo");
181 assert_se(streq(actual, "foo"));
182
183 actual = strjoina(NULL);
184 assert_se(streq(actual, ""));
185
186 actual = strjoina(NULL, "foo");
187 assert_se(streq(actual, ""));
188
189 actual = strjoina("foo", NULL, "bar");
190 assert_se(streq(actual, "foo"));
191}
192
193static void test_strcmp_ptr(void) {
194 assert_se(strcmp_ptr(NULL, NULL) == 0);
195 assert_se(strcmp_ptr("", NULL) > 0);
196 assert_se(strcmp_ptr("foo", NULL) > 0);
197 assert_se(strcmp_ptr(NULL, "") < 0);
198 assert_se(strcmp_ptr(NULL, "bar") < 0);
199 assert_se(strcmp_ptr("foo", "bar") > 0);
200 assert_se(strcmp_ptr("bar", "baz") < 0);
201 assert_se(strcmp_ptr("foo", "foo") == 0);
202 assert_se(strcmp_ptr("", "") == 0);
203}
204
205static void test_foreach_word(void) {
206 const char *word, *state;
207 size_t l;
208 int i = 0;
209 const char test[] = "test abc d\te f ";
210 const char * const expected[] = {
211 "test",
212 "abc",
213 "d",
214 "e",
215 "f",
216 "",
217 NULL
218 };
219
220 FOREACH_WORD(word, l, test, state)
221 assert_se(strneq(expected[i++], word, l));
222}
223
224static void check(const char *test, char** expected, bool trailing) {
bc8ec170 225 int i = 0, r;
6571a64e
RC
226
227 printf("<<<%s>>>\n", test);
bc8ec170
ZJS
228 for (;;) {
229 _cleanup_free_ char *word = NULL;
230
231 r = extract_first_word(&test, &word, NULL, EXTRACT_QUOTES);
232 if (r == 0) {
233 assert_se(!trailing);
234 break;
235 } else if (r < 0) {
236 assert_se(trailing);
237 break;
238 }
239
240 assert_se(streq(word, expected[i++]));
241 printf("<%s>\n", word);
6571a64e 242 }
6571a64e 243 assert_se(expected[i] == NULL);
6571a64e
RC
244}
245
246static void test_foreach_word_quoted(void) {
247 check("test a b c 'd' e '' '' hhh '' '' \"a b c\"",
248 STRV_MAKE("test",
249 "a",
250 "b",
251 "c",
252 "d",
253 "e",
254 "",
255 "",
256 "hhh",
257 "",
258 "",
259 "a b c"),
260 false);
261
262 check("test \"xxx",
263 STRV_MAKE("test"),
264 true);
265
266 check("test\\",
267 STRV_MAKE_EMPTY,
268 true);
269}
270
271static void test_endswith(void) {
272 assert_se(endswith("foobar", "bar"));
273 assert_se(endswith("foobar", ""));
274 assert_se(endswith("foobar", "foobar"));
275 assert_se(endswith("", ""));
276
277 assert_se(!endswith("foobar", "foo"));
278 assert_se(!endswith("foobar", "foobarfoofoo"));
279}
280
281static void test_endswith_no_case(void) {
282 assert_se(endswith_no_case("fooBAR", "bar"));
283 assert_se(endswith_no_case("foobar", ""));
284 assert_se(endswith_no_case("foobar", "FOOBAR"));
285 assert_se(endswith_no_case("", ""));
286
287 assert_se(!endswith_no_case("foobar", "FOO"));
288 assert_se(!endswith_no_case("foobar", "FOOBARFOOFOO"));
289}
290
291static void test_delete_chars(void) {
7546145e
LP
292 char *s, input[] = " hello, waldo. abc";
293
294 s = delete_chars(input, WHITESPACE);
295 assert_se(streq(s, "hello,waldo.abc"));
296 assert_se(s == input);
297}
298
299static void test_delete_trailing_chars(void) {
300
301 char *s,
302 input1[] = " \n \r k \n \r ",
303 input2[] = "kkkkthiskkkiskkkaktestkkk",
304 input3[] = "abcdef";
305
306 s = delete_trailing_chars(input1, WHITESPACE);
307 assert_se(streq(s, " \n \r k"));
308 assert_se(s == input1);
309
310 s = delete_trailing_chars(input2, "kt");
311 assert_se(streq(s, "kkkkthiskkkiskkkaktes"));
312 assert_se(s == input2);
313
314 s = delete_trailing_chars(input3, WHITESPACE);
315 assert_se(streq(s, "abcdef"));
316 assert_se(s == input3);
317
318 s = delete_trailing_chars(input3, "fe");
319 assert_se(streq(s, "abcd"));
320 assert_se(s == input3);
321}
322
ca4d708d
ZJS
323static void test_delete_trailing_slashes(void) {
324 char s1[] = "foobar//",
325 s2[] = "foobar/",
326 s3[] = "foobar",
327 s4[] = "";
328
329 assert_se(streq(delete_trailing_chars(s1, "_"), "foobar//"));
330 assert_se(streq(delete_trailing_chars(s1, "/"), "foobar"));
331 assert_se(streq(delete_trailing_chars(s2, "/"), "foobar"));
332 assert_se(streq(delete_trailing_chars(s3, "/"), "foobar"));
333 assert_se(streq(delete_trailing_chars(s4, "/"), ""));
334}
335
7546145e
LP
336static void test_skip_leading_chars(void) {
337 char input1[] = " \n \r k \n \r ",
338 input2[] = "kkkkthiskkkiskkkaktestkkk",
339 input3[] = "abcdef";
6571a64e 340
7546145e
LP
341 assert_se(streq(skip_leading_chars(input1, WHITESPACE), "k \n \r "));
342 assert_se(streq(skip_leading_chars(input2, "k"), "thiskkkiskkkaktestkkk"));
343 assert_se(streq(skip_leading_chars(input2, "tk"), "hiskkkiskkkaktestkkk"));
344 assert_se(streq(skip_leading_chars(input3, WHITESPACE), "abcdef"));
345 assert_se(streq(skip_leading_chars(input3, "bcaef"), "def"));
6571a64e
RC
346}
347
348static void test_in_charset(void) {
349 assert_se(in_charset("dddaaabbbcccc", "abcd"));
350 assert_se(!in_charset("dddaaabbbcccc", "abc f"));
351}
352
353static void test_split_pair(void) {
354 _cleanup_free_ char *a = NULL, *b = NULL;
355
356 assert_se(split_pair("", "", &a, &b) == -EINVAL);
357 assert_se(split_pair("foo=bar", "", &a, &b) == -EINVAL);
358 assert_se(split_pair("", "=", &a, &b) == -EINVAL);
359 assert_se(split_pair("foo=bar", "=", &a, &b) >= 0);
360 assert_se(streq(a, "foo"));
361 assert_se(streq(b, "bar"));
362 free(a);
363 free(b);
364 assert_se(split_pair("==", "==", &a, &b) >= 0);
365 assert_se(streq(a, ""));
366 assert_se(streq(b, ""));
367 free(a);
368 free(b);
369
370 assert_se(split_pair("===", "==", &a, &b) >= 0);
371 assert_se(streq(a, ""));
372 assert_se(streq(b, "="));
373}
374
375static void test_first_word(void) {
376 assert_se(first_word("Hello", ""));
377 assert_se(first_word("Hello", "Hello"));
378 assert_se(first_word("Hello world", "Hello"));
379 assert_se(first_word("Hello\tworld", "Hello"));
380 assert_se(first_word("Hello\nworld", "Hello"));
381 assert_se(first_word("Hello\rworld", "Hello"));
382 assert_se(first_word("Hello ", "Hello"));
383
384 assert_se(!first_word("Hello", "Hellooo"));
385 assert_se(!first_word("Hello", "xxxxx"));
386 assert_se(!first_word("Hellooo", "Hello"));
387}
388
7bf7ce28
LP
389static void test_strlen_ptr(void) {
390 assert_se(strlen_ptr("foo") == 3);
391 assert_se(strlen_ptr("") == 0);
392 assert_se(strlen_ptr(NULL) == 0);
393}
394
9fe4ea21
LP
395int main(int argc, char *argv[]) {
396 test_string_erase();
522d85ae 397 test_ascii_strcasecmp_n();
c1749834 398 test_ascii_strcasecmp_nn();
6571a64e
RC
399 test_streq_ptr();
400 test_strstrip();
401 test_strextend();
402 test_strrep();
403 test_strappend();
404 test_string_has_cc();
405 test_ascii_strlower();
406 test_strshorten();
407 test_strjoina();
408 test_strcmp_ptr();
409 test_foreach_word();
410 test_foreach_word_quoted();
411 test_endswith();
412 test_endswith_no_case();
413 test_delete_chars();
7546145e 414 test_delete_trailing_chars();
ca4d708d 415 test_delete_trailing_slashes();
7546145e 416 test_skip_leading_chars();
6571a64e
RC
417 test_in_charset();
418 test_split_pair();
419 test_first_word();
7bf7ce28 420 test_strlen_ptr();
6571a64e 421
9fe4ea21
LP
422 return 0;
423}