1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2010 Lennart Poettering
6 Copyright 2013 Thomas H.P. Andersen
13 #include "extract-word.h"
15 #include "string-util.h"
17 static void test_extract_first_word(void) {
18 const char *p, *original;
21 p = original = "foobar waldo";
22 assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
23 assert_se(streq(t, "foobar"));
25 assert_se(p == original + 7);
27 assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
28 assert_se(streq(t, "waldo"));
30 assert_se(isempty(p));
32 assert_se(extract_first_word(&p, &t, NULL, 0) == 0);
34 assert_se(isempty(p));
36 p = original = "\"foobar\" \'waldo\'";
37 assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
38 assert_se(streq(t, "\"foobar\""));
40 assert_se(p == original + 9);
42 assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
43 assert_se(streq(t, "\'waldo\'"));
45 assert_se(isempty(p));
47 assert_se(extract_first_word(&p, &t, NULL, 0) == 0);
49 assert_se(isempty(p));
51 p = original = "\"foobar\" \'waldo\'";
52 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) > 0);
53 assert_se(streq(t, "foobar"));
55 assert_se(p == original + 9);
57 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) > 0);
58 assert_se(streq(t, "waldo"));
60 assert_se(isempty(p));
62 assert_se(extract_first_word(&p, &t, NULL, 0) == 0);
64 assert_se(isempty(p));
67 assert_se(extract_first_word(&p, &t, NULL, 0) == 1);
68 assert_se(streq(t, "\""));
70 assert_se(isempty(p));
73 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) == -EINVAL);
74 assert_se(p == original + 1);
77 assert_se(extract_first_word(&p, &t, NULL, 0) == 1);
78 assert_se(streq(t, "\'"));
80 assert_se(isempty(p));
83 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) == -EINVAL);
84 assert_se(p == original + 1);
86 p = original = "\'fooo";
87 assert_se(extract_first_word(&p, &t, NULL, 0) == 1);
88 assert_se(streq(t, "\'fooo"));
90 assert_se(isempty(p));
92 p = original = "\'fooo";
93 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) == -EINVAL);
94 assert_se(p == original + 5);
96 p = original = "\'fooo";
97 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_RELAX) > 0);
98 assert_se(streq(t, "fooo"));
100 assert_se(isempty(p));
102 p = original = "\"fooo";
103 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_RELAX) > 0);
104 assert_se(streq(t, "fooo"));
106 assert_se(isempty(p));
108 p = original = "yay\'foo\'bar";
109 assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
110 assert_se(streq(t, "yay\'foo\'bar"));
112 assert_se(isempty(p));
114 p = original = "yay\'foo\'bar";
115 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) > 0);
116 assert_se(streq(t, "yayfoobar"));
118 assert_se(isempty(p));
120 p = original = " foobar ";
121 assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
122 assert_se(streq(t, "foobar"));
124 assert_se(isempty(p));
126 p = original = " foo\\ba\\x6ar ";
127 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE) > 0);
128 assert_se(streq(t, "foo\ba\x6ar"));
130 assert_se(isempty(p));
132 p = original = " foo\\ba\\x6ar ";
133 assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
134 assert_se(streq(t, "foobax6ar"));
136 assert_se(isempty(p));
138 p = original = " f\\u00f6o \"pi\\U0001F4A9le\" ";
139 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE) > 0);
140 assert_se(streq(t, "föo"));
142 assert_se(p == original + 13);
144 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE) > 0);
145 assert_se(streq(t, "pi\360\237\222\251le"));
147 assert_se(isempty(p));
149 p = original = "fooo\\";
150 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_RELAX) > 0);
151 assert_se(streq(t, "fooo"));
153 assert_se(isempty(p));
155 p = original = "fooo\\";
156 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE_RELAX) > 0);
157 assert_se(streq(t, "fooo\\"));
159 assert_se(isempty(p));
161 p = original = "fooo\\";
162 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE_RELAX|EXTRACT_RELAX) > 0);
163 assert_se(streq(t, "fooo\\"));
165 assert_se(isempty(p));
167 p = original = "fooo\\";
168 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE|EXTRACT_CUNESCAPE_RELAX) > 0);
169 assert_se(streq(t, "fooo\\"));
171 assert_se(isempty(p));
173 p = original = "\"foo\\";
174 assert_se(extract_first_word(&p, &t, NULL, 0) == -EINVAL);
175 assert_se(p == original + 5);
177 p = original = "\"foo\\";
178 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_RELAX) > 0);
179 assert_se(streq(t, "foo"));
181 assert_se(isempty(p));
183 p = original = "foo::bar";
184 assert_se(extract_first_word(&p, &t, ":", 0) == 1);
185 assert_se(streq(t, "foo"));
187 assert_se(p == original + 5);
189 assert_se(extract_first_word(&p, &t, ":", 0) == 1);
190 assert_se(streq(t, "bar"));
192 assert_se(isempty(p));
194 assert_se(extract_first_word(&p, &t, ":", 0) == 0);
196 assert_se(isempty(p));
198 p = original = "foo\\:bar::waldo";
199 assert_se(extract_first_word(&p, &t, ":", 0) == 1);
200 assert_se(streq(t, "foo:bar"));
202 assert_se(p == original + 10);
204 assert_se(extract_first_word(&p, &t, ":", 0) == 1);
205 assert_se(streq(t, "waldo"));
207 assert_se(isempty(p));
209 assert_se(extract_first_word(&p, &t, ":", 0) == 0);
211 assert_se(isempty(p));
213 p = original = "\"foo\\";
214 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE_RELAX) == -EINVAL);
215 assert_se(p == original + 5);
217 p = original = "\"foo\\";
218 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE_RELAX|EXTRACT_RELAX) > 0);
219 assert_se(streq(t, "foo\\"));
221 assert_se(isempty(p));
223 p = original = "\"foo\\";
224 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE|EXTRACT_CUNESCAPE_RELAX|EXTRACT_RELAX) > 0);
225 assert_se(streq(t, "foo\\"));
227 assert_se(isempty(p));
229 p = original = "fooo\\ bar quux";
230 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_RELAX) > 0);
231 assert_se(streq(t, "fooo bar"));
233 assert_se(p == original + 10);
235 p = original = "fooo\\ bar quux";
236 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE_RELAX) > 0);
237 assert_se(streq(t, "fooo bar"));
239 assert_se(p == original + 10);
241 p = original = "fooo\\ bar quux";
242 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE_RELAX|EXTRACT_RELAX) > 0);
243 assert_se(streq(t, "fooo bar"));
245 assert_se(p == original + 10);
247 p = original = "fooo\\ bar quux";
248 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE) == -EINVAL);
249 assert_se(p == original + 5);
251 p = original = "fooo\\ bar quux";
252 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE|EXTRACT_CUNESCAPE_RELAX) > 0);
253 assert_se(streq(t, "fooo\\ bar"));
255 assert_se(p == original + 10);
257 p = original = "\\w+@\\K[\\d.]+";
258 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE) == -EINVAL);
259 assert_se(p == original + 1);
261 p = original = "\\w+@\\K[\\d.]+";
262 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE|EXTRACT_CUNESCAPE_RELAX) > 0);
263 assert_se(streq(t, "\\w+@\\K[\\d.]+"));
265 assert_se(isempty(p));
267 p = original = "\\w+\\b";
268 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE|EXTRACT_CUNESCAPE_RELAX) > 0);
269 assert_se(streq(t, "\\w+\b"));
271 assert_se(isempty(p));
273 p = original = "-N ''";
274 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) > 0);
275 assert_se(streq(t, "-N"));
277 assert_se(p == original + 3);
279 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) > 0);
280 assert_se(streq(t, ""));
282 assert_se(isempty(p));
284 p = original = ":foo\\:bar::waldo:";
285 assert_se(extract_first_word(&p, &t, ":", EXTRACT_DONT_COALESCE_SEPARATORS) == 1);
287 assert_se(streq(t, ""));
289 assert_se(p == original + 1);
291 assert_se(extract_first_word(&p, &t, ":", EXTRACT_DONT_COALESCE_SEPARATORS) == 1);
292 assert_se(streq(t, "foo:bar"));
294 assert_se(p == original + 10);
296 assert_se(extract_first_word(&p, &t, ":", EXTRACT_DONT_COALESCE_SEPARATORS) == 1);
298 assert_se(streq(t, ""));
300 assert_se(p == original + 11);
302 assert_se(extract_first_word(&p, &t, ":", EXTRACT_DONT_COALESCE_SEPARATORS) == 1);
303 assert_se(streq(t, "waldo"));
305 assert_se(p == original + 17);
307 assert_se(extract_first_word(&p, &t, ":", EXTRACT_DONT_COALESCE_SEPARATORS) == 1);
308 assert_se(streq(t, ""));
310 assert_se(p == NULL);
312 assert_se(extract_first_word(&p, &t, ":", EXTRACT_DONT_COALESCE_SEPARATORS) == 0);
317 assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
318 assert_se(streq(t, "fooxbar"));
320 assert_se(p == NULL);
323 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_RETAIN_ESCAPE) > 0);
324 assert_se(streq(t, "foo\\xbar"));
326 assert_se(p == NULL);
329 #if 0 /// UNNEEDED by elogind
330 static void test_extract_first_word_and_warn(void) {
331 const char *p, *original;
334 p = original = "foobar waldo";
335 assert_se(extract_first_word_and_warn(&p, &t, NULL, 0, NULL, "fake", 1, original) > 0);
336 assert_se(streq(t, "foobar"));
338 assert_se(p == original + 7);
340 assert_se(extract_first_word_and_warn(&p, &t, NULL, 0, NULL, "fake", 1, original) > 0);
341 assert_se(streq(t, "waldo"));
343 assert_se(isempty(p));
345 assert_se(extract_first_word_and_warn(&p, &t, NULL, 0, NULL, "fake", 1, original) == 0);
347 assert_se(isempty(p));
349 p = original = "\"foobar\" \'waldo\'";
350 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES, NULL, "fake", 1, original) > 0);
351 assert_se(streq(t, "foobar"));
353 assert_se(p == original + 9);
355 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES, NULL, "fake", 1, original) > 0);
356 assert_se(streq(t, "waldo"));
358 assert_se(isempty(p));
360 assert_se(extract_first_word_and_warn(&p, &t, NULL, 0, NULL, "fake", 1, original) == 0);
362 assert_se(isempty(p));
365 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES, NULL, "fake", 1, original) == -EINVAL);
366 assert_se(p == original + 1);
369 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES, NULL, "fake", 1, original) == -EINVAL);
370 assert_se(p == original + 1);
372 p = original = "\'fooo";
373 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES, NULL, "fake", 1, original) == -EINVAL);
374 assert_se(p == original + 5);
376 p = original = "\'fooo";
377 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_RELAX, NULL, "fake", 1, original) > 0);
378 assert_se(streq(t, "fooo"));
380 assert_se(isempty(p));
382 p = original = " foo\\ba\\x6ar ";
383 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_CUNESCAPE, NULL, "fake", 1, original) > 0);
384 assert_se(streq(t, "foo\ba\x6ar"));
386 assert_se(isempty(p));
388 p = original = " foo\\ba\\x6ar ";
389 assert_se(extract_first_word_and_warn(&p, &t, NULL, 0, NULL, "fake", 1, original) > 0);
390 assert_se(streq(t, "foobax6ar"));
392 assert_se(isempty(p));
394 p = original = " f\\u00f6o \"pi\\U0001F4A9le\" ";
395 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_CUNESCAPE, NULL, "fake", 1, original) > 0);
396 assert_se(streq(t, "föo"));
398 assert_se(p == original + 13);
400 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE, NULL, "fake", 1, original) > 0);
401 assert_se(streq(t, "pi\360\237\222\251le"));
403 assert_se(isempty(p));
405 p = original = "fooo\\";
406 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_RELAX, NULL, "fake", 1, original) > 0);
407 assert_se(streq(t, "fooo"));
409 assert_se(isempty(p));
411 p = original = "fooo\\";
412 assert_se(extract_first_word_and_warn(&p, &t, NULL, 0, NULL, "fake", 1, original) > 0);
413 assert_se(streq(t, "fooo\\"));
415 assert_se(isempty(p));
417 p = original = "fooo\\";
418 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_CUNESCAPE, NULL, "fake", 1, original) > 0);
419 assert_se(streq(t, "fooo\\"));
421 assert_se(isempty(p));
423 p = original = "\"foo\\";
424 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES, NULL, "fake", 1, original) == -EINVAL);
425 assert_se(p == original + 5);
427 p = original = "\"foo\\";
428 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_RELAX, NULL, "fake", 1, original) > 0);
429 assert_se(streq(t, "foo"));
431 assert_se(isempty(p));
433 p = original = "\"foo\\";
434 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE, NULL, "fake", 1, original) == -EINVAL);
435 assert_se(p == original + 5);
437 p = original = "\"foo\\";
438 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE|EXTRACT_RELAX, NULL, "fake", 1, original) > 0);
439 assert_se(streq(t, "foo"));
441 assert_se(isempty(p));
443 p = original = "fooo\\ bar quux";
444 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_RELAX, NULL, "fake", 1, original) > 0);
445 assert_se(streq(t, "fooo bar"));
447 assert_se(p == original + 10);
449 p = original = "fooo\\ bar quux";
450 assert_se(extract_first_word_and_warn(&p, &t, NULL, 0, NULL, "fake", 1, original) > 0);
451 assert_se(streq(t, "fooo bar"));
453 assert_se(p == original + 10);
455 p = original = "fooo\\ bar quux";
456 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_CUNESCAPE, NULL, "fake", 1, original) > 0);
457 assert_se(streq(t, "fooo\\ bar"));
459 assert_se(p == original + 10);
461 p = original = "\\w+@\\K[\\d.]+";
462 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_CUNESCAPE, NULL, "fake", 1, original) > 0);
463 assert_se(streq(t, "\\w+@\\K[\\d.]+"));
465 assert_se(isempty(p));
467 p = original = "\\w+\\b";
468 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_CUNESCAPE, NULL, "fake", 1, original) > 0);
469 assert_se(streq(t, "\\w+\b"));
471 assert_se(isempty(p));
474 static void test_extract_many_words(void) {
475 const char *p, *original;
478 p = original = "foobar waldi piep";
479 assert_se(extract_many_words(&p, NULL, 0, &a, &b, &c, NULL) == 3);
480 assert_se(isempty(p));
481 assert_se(streq_ptr(a, "foobar"));
482 assert_se(streq_ptr(b, "waldi"));
483 assert_se(streq_ptr(c, "piep"));
488 p = original = "'foobar' wa\"ld\"i ";
489 assert_se(extract_many_words(&p, NULL, 0, &a, &b, &c, NULL) == 2);
490 assert_se(isempty(p));
491 assert_se(streq_ptr(a, "'foobar'"));
492 assert_se(streq_ptr(b, "wa\"ld\"i"));
493 assert_se(streq_ptr(c, NULL));
497 p = original = "'foobar' wa\"ld\"i ";
498 assert_se(extract_many_words(&p, NULL, EXTRACT_QUOTES, &a, &b, &c, NULL) == 2);
499 assert_se(isempty(p));
500 assert_se(streq_ptr(a, "foobar"));
501 assert_se(streq_ptr(b, "waldi"));
502 assert_se(streq_ptr(c, NULL));
507 assert_se(extract_many_words(&p, NULL, 0, &a, &b, &c, NULL) == 0);
508 assert_se(isempty(p));
509 assert_se(streq_ptr(a, NULL));
510 assert_se(streq_ptr(b, NULL));
511 assert_se(streq_ptr(c, NULL));
514 assert_se(extract_many_words(&p, NULL, 0, &a, &b, &c, NULL) == 0);
515 assert_se(isempty(p));
516 assert_se(streq_ptr(a, NULL));
517 assert_se(streq_ptr(b, NULL));
518 assert_se(streq_ptr(c, NULL));
520 p = original = "foobar";
521 assert_se(extract_many_words(&p, NULL, 0, NULL) == 0);
522 assert_se(p == original);
524 p = original = "foobar waldi";
525 assert_se(extract_many_words(&p, NULL, 0, &a, NULL) == 1);
526 assert_se(p == original+7);
527 assert_se(streq_ptr(a, "foobar"));
530 p = original = " foobar ";
531 assert_se(extract_many_words(&p, NULL, 0, &a, NULL) == 1);
532 assert_se(isempty(p));
533 assert_se(streq_ptr(a, "foobar"));
538 int main(int argc, char *argv[]) {
539 log_parse_environment();
542 test_extract_first_word();
543 #if 0 /// UNNEEDED by elogind
544 test_extract_first_word_and_warn();
545 test_extract_many_words();