1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 Copyright 2010 Lennart Poettering
4 Copyright 2013 Thomas H.P. Andersen
11 #include "extract-word.h"
13 #include "string-util.h"
15 static void test_extract_first_word(void) {
16 const char *p, *original;
19 p = original = "foobar waldo";
20 assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
21 assert_se(streq(t, "foobar"));
23 assert_se(p == original + 7);
25 assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
26 assert_se(streq(t, "waldo"));
28 assert_se(isempty(p));
30 assert_se(extract_first_word(&p, &t, NULL, 0) == 0);
32 assert_se(isempty(p));
34 p = original = "\"foobar\" \'waldo\'";
35 assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
36 assert_se(streq(t, "\"foobar\""));
38 assert_se(p == original + 9);
40 assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
41 assert_se(streq(t, "\'waldo\'"));
43 assert_se(isempty(p));
45 assert_se(extract_first_word(&p, &t, NULL, 0) == 0);
47 assert_se(isempty(p));
49 p = original = "\"foobar\" \'waldo\'";
50 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) > 0);
51 assert_se(streq(t, "foobar"));
53 assert_se(p == original + 9);
55 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) > 0);
56 assert_se(streq(t, "waldo"));
58 assert_se(isempty(p));
60 assert_se(extract_first_word(&p, &t, NULL, 0) == 0);
62 assert_se(isempty(p));
65 assert_se(extract_first_word(&p, &t, NULL, 0) == 1);
66 assert_se(streq(t, "\""));
68 assert_se(isempty(p));
71 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) == -EINVAL);
72 assert_se(p == original + 1);
75 assert_se(extract_first_word(&p, &t, NULL, 0) == 1);
76 assert_se(streq(t, "\'"));
78 assert_se(isempty(p));
81 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) == -EINVAL);
82 assert_se(p == original + 1);
84 p = original = "\'fooo";
85 assert_se(extract_first_word(&p, &t, NULL, 0) == 1);
86 assert_se(streq(t, "\'fooo"));
88 assert_se(isempty(p));
90 p = original = "\'fooo";
91 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) == -EINVAL);
92 assert_se(p == original + 5);
94 p = original = "\'fooo";
95 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_RELAX) > 0);
96 assert_se(streq(t, "fooo"));
98 assert_se(isempty(p));
100 p = original = "\"fooo";
101 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_RELAX) > 0);
102 assert_se(streq(t, "fooo"));
104 assert_se(isempty(p));
106 p = original = "yay\'foo\'bar";
107 assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
108 assert_se(streq(t, "yay\'foo\'bar"));
110 assert_se(isempty(p));
112 p = original = "yay\'foo\'bar";
113 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) > 0);
114 assert_se(streq(t, "yayfoobar"));
116 assert_se(isempty(p));
118 p = original = " foobar ";
119 assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
120 assert_se(streq(t, "foobar"));
122 assert_se(isempty(p));
124 p = original = " foo\\ba\\x6ar ";
125 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE) > 0);
126 assert_se(streq(t, "foo\ba\x6ar"));
128 assert_se(isempty(p));
130 p = original = " foo\\ba\\x6ar ";
131 assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
132 assert_se(streq(t, "foobax6ar"));
134 assert_se(isempty(p));
136 p = original = " f\\u00f6o \"pi\\U0001F4A9le\" ";
137 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE) > 0);
138 assert_se(streq(t, "föo"));
140 assert_se(p == original + 13);
142 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE) > 0);
143 assert_se(streq(t, "pi\360\237\222\251le"));
145 assert_se(isempty(p));
147 p = original = "fooo\\";
148 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_RELAX) > 0);
149 assert_se(streq(t, "fooo"));
151 assert_se(isempty(p));
153 p = original = "fooo\\";
154 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE_RELAX) > 0);
155 assert_se(streq(t, "fooo\\"));
157 assert_se(isempty(p));
159 p = original = "fooo\\";
160 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE_RELAX|EXTRACT_RELAX) > 0);
161 assert_se(streq(t, "fooo\\"));
163 assert_se(isempty(p));
165 p = original = "fooo\\";
166 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE|EXTRACT_CUNESCAPE_RELAX) > 0);
167 assert_se(streq(t, "fooo\\"));
169 assert_se(isempty(p));
171 p = original = "\"foo\\";
172 assert_se(extract_first_word(&p, &t, NULL, 0) == -EINVAL);
173 assert_se(p == original + 5);
175 p = original = "\"foo\\";
176 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_RELAX) > 0);
177 assert_se(streq(t, "foo"));
179 assert_se(isempty(p));
181 p = original = "foo::bar";
182 assert_se(extract_first_word(&p, &t, ":", 0) == 1);
183 assert_se(streq(t, "foo"));
185 assert_se(p == original + 5);
187 assert_se(extract_first_word(&p, &t, ":", 0) == 1);
188 assert_se(streq(t, "bar"));
190 assert_se(isempty(p));
192 assert_se(extract_first_word(&p, &t, ":", 0) == 0);
194 assert_se(isempty(p));
196 p = original = "foo\\:bar::waldo";
197 assert_se(extract_first_word(&p, &t, ":", 0) == 1);
198 assert_se(streq(t, "foo:bar"));
200 assert_se(p == original + 10);
202 assert_se(extract_first_word(&p, &t, ":", 0) == 1);
203 assert_se(streq(t, "waldo"));
205 assert_se(isempty(p));
207 assert_se(extract_first_word(&p, &t, ":", 0) == 0);
209 assert_se(isempty(p));
211 p = original = "\"foo\\";
212 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE_RELAX) == -EINVAL);
213 assert_se(p == original + 5);
215 p = original = "\"foo\\";
216 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE_RELAX|EXTRACT_RELAX) > 0);
217 assert_se(streq(t, "foo\\"));
219 assert_se(isempty(p));
221 p = original = "\"foo\\";
222 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE|EXTRACT_CUNESCAPE_RELAX|EXTRACT_RELAX) > 0);
223 assert_se(streq(t, "foo\\"));
225 assert_se(isempty(p));
227 p = original = "fooo\\ bar quux";
228 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_RELAX) > 0);
229 assert_se(streq(t, "fooo bar"));
231 assert_se(p == original + 10);
233 p = original = "fooo\\ bar quux";
234 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE_RELAX) > 0);
235 assert_se(streq(t, "fooo bar"));
237 assert_se(p == original + 10);
239 p = original = "fooo\\ bar quux";
240 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE_RELAX|EXTRACT_RELAX) > 0);
241 assert_se(streq(t, "fooo bar"));
243 assert_se(p == original + 10);
245 p = original = "fooo\\ bar quux";
246 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE) == -EINVAL);
247 assert_se(p == original + 5);
249 p = original = "fooo\\ bar quux";
250 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE|EXTRACT_CUNESCAPE_RELAX) > 0);
251 assert_se(streq(t, "fooo\\ bar"));
253 assert_se(p == original + 10);
255 p = original = "\\w+@\\K[\\d.]+";
256 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE) == -EINVAL);
257 assert_se(p == original + 1);
259 p = original = "\\w+@\\K[\\d.]+";
260 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE|EXTRACT_CUNESCAPE_RELAX) > 0);
261 assert_se(streq(t, "\\w+@\\K[\\d.]+"));
263 assert_se(isempty(p));
265 p = original = "\\w+\\b";
266 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE|EXTRACT_CUNESCAPE_RELAX) > 0);
267 assert_se(streq(t, "\\w+\b"));
269 assert_se(isempty(p));
271 p = original = "-N ''";
272 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) > 0);
273 assert_se(streq(t, "-N"));
275 assert_se(p == original + 3);
277 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) > 0);
278 assert_se(streq(t, ""));
280 assert_se(isempty(p));
282 p = original = ":foo\\:bar::waldo:";
283 assert_se(extract_first_word(&p, &t, ":", EXTRACT_DONT_COALESCE_SEPARATORS) == 1);
285 assert_se(streq(t, ""));
287 assert_se(p == original + 1);
289 assert_se(extract_first_word(&p, &t, ":", EXTRACT_DONT_COALESCE_SEPARATORS) == 1);
290 assert_se(streq(t, "foo:bar"));
292 assert_se(p == original + 10);
294 assert_se(extract_first_word(&p, &t, ":", EXTRACT_DONT_COALESCE_SEPARATORS) == 1);
296 assert_se(streq(t, ""));
298 assert_se(p == original + 11);
300 assert_se(extract_first_word(&p, &t, ":", EXTRACT_DONT_COALESCE_SEPARATORS) == 1);
301 assert_se(streq(t, "waldo"));
303 assert_se(p == original + 17);
305 assert_se(extract_first_word(&p, &t, ":", EXTRACT_DONT_COALESCE_SEPARATORS) == 1);
306 assert_se(streq(t, ""));
308 assert_se(p == NULL);
310 assert_se(extract_first_word(&p, &t, ":", EXTRACT_DONT_COALESCE_SEPARATORS) == 0);
315 assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
316 assert_se(streq(t, "fooxbar"));
318 assert_se(p == NULL);
321 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_RETAIN_ESCAPE) > 0);
322 assert_se(streq(t, "foo\\xbar"));
324 assert_se(p == NULL);
327 #if 0 /// UNNEEDED by elogind
328 static void test_extract_first_word_and_warn(void) {
329 const char *p, *original;
332 p = original = "foobar waldo";
333 assert_se(extract_first_word_and_warn(&p, &t, NULL, 0, NULL, "fake", 1, original) > 0);
334 assert_se(streq(t, "foobar"));
336 assert_se(p == original + 7);
338 assert_se(extract_first_word_and_warn(&p, &t, NULL, 0, NULL, "fake", 1, original) > 0);
339 assert_se(streq(t, "waldo"));
341 assert_se(isempty(p));
343 assert_se(extract_first_word_and_warn(&p, &t, NULL, 0, NULL, "fake", 1, original) == 0);
345 assert_se(isempty(p));
347 p = original = "\"foobar\" \'waldo\'";
348 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES, NULL, "fake", 1, original) > 0);
349 assert_se(streq(t, "foobar"));
351 assert_se(p == original + 9);
353 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES, NULL, "fake", 1, original) > 0);
354 assert_se(streq(t, "waldo"));
356 assert_se(isempty(p));
358 assert_se(extract_first_word_and_warn(&p, &t, NULL, 0, NULL, "fake", 1, original) == 0);
360 assert_se(isempty(p));
363 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES, NULL, "fake", 1, original) == -EINVAL);
364 assert_se(p == original + 1);
367 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES, NULL, "fake", 1, original) == -EINVAL);
368 assert_se(p == original + 1);
370 p = original = "\'fooo";
371 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES, NULL, "fake", 1, original) == -EINVAL);
372 assert_se(p == original + 5);
374 p = original = "\'fooo";
375 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_RELAX, NULL, "fake", 1, original) > 0);
376 assert_se(streq(t, "fooo"));
378 assert_se(isempty(p));
380 p = original = " foo\\ba\\x6ar ";
381 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_CUNESCAPE, NULL, "fake", 1, original) > 0);
382 assert_se(streq(t, "foo\ba\x6ar"));
384 assert_se(isempty(p));
386 p = original = " foo\\ba\\x6ar ";
387 assert_se(extract_first_word_and_warn(&p, &t, NULL, 0, NULL, "fake", 1, original) > 0);
388 assert_se(streq(t, "foobax6ar"));
390 assert_se(isempty(p));
392 p = original = " f\\u00f6o \"pi\\U0001F4A9le\" ";
393 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_CUNESCAPE, NULL, "fake", 1, original) > 0);
394 assert_se(streq(t, "föo"));
396 assert_se(p == original + 13);
398 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE, NULL, "fake", 1, original) > 0);
399 assert_se(streq(t, "pi\360\237\222\251le"));
401 assert_se(isempty(p));
403 p = original = "fooo\\";
404 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_RELAX, NULL, "fake", 1, original) > 0);
405 assert_se(streq(t, "fooo"));
407 assert_se(isempty(p));
409 p = original = "fooo\\";
410 assert_se(extract_first_word_and_warn(&p, &t, NULL, 0, NULL, "fake", 1, original) > 0);
411 assert_se(streq(t, "fooo\\"));
413 assert_se(isempty(p));
415 p = original = "fooo\\";
416 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_CUNESCAPE, NULL, "fake", 1, original) > 0);
417 assert_se(streq(t, "fooo\\"));
419 assert_se(isempty(p));
421 p = original = "\"foo\\";
422 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES, NULL, "fake", 1, original) == -EINVAL);
423 assert_se(p == original + 5);
425 p = original = "\"foo\\";
426 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_RELAX, NULL, "fake", 1, original) > 0);
427 assert_se(streq(t, "foo"));
429 assert_se(isempty(p));
431 p = original = "\"foo\\";
432 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE, NULL, "fake", 1, original) == -EINVAL);
433 assert_se(p == original + 5);
435 p = original = "\"foo\\";
436 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE|EXTRACT_RELAX, NULL, "fake", 1, original) > 0);
437 assert_se(streq(t, "foo"));
439 assert_se(isempty(p));
441 p = original = "fooo\\ bar quux";
442 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_RELAX, NULL, "fake", 1, original) > 0);
443 assert_se(streq(t, "fooo bar"));
445 assert_se(p == original + 10);
447 p = original = "fooo\\ bar quux";
448 assert_se(extract_first_word_and_warn(&p, &t, NULL, 0, NULL, "fake", 1, original) > 0);
449 assert_se(streq(t, "fooo bar"));
451 assert_se(p == original + 10);
453 p = original = "fooo\\ bar quux";
454 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_CUNESCAPE, NULL, "fake", 1, original) > 0);
455 assert_se(streq(t, "fooo\\ bar"));
457 assert_se(p == original + 10);
459 p = original = "\\w+@\\K[\\d.]+";
460 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_CUNESCAPE, NULL, "fake", 1, original) > 0);
461 assert_se(streq(t, "\\w+@\\K[\\d.]+"));
463 assert_se(isempty(p));
465 p = original = "\\w+\\b";
466 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_CUNESCAPE, NULL, "fake", 1, original) > 0);
467 assert_se(streq(t, "\\w+\b"));
469 assert_se(isempty(p));
472 static void test_extract_many_words(void) {
473 const char *p, *original;
476 p = original = "foobar waldi piep";
477 assert_se(extract_many_words(&p, NULL, 0, &a, &b, &c, NULL) == 3);
478 assert_se(isempty(p));
479 assert_se(streq_ptr(a, "foobar"));
480 assert_se(streq_ptr(b, "waldi"));
481 assert_se(streq_ptr(c, "piep"));
486 p = original = "'foobar' wa\"ld\"i ";
487 assert_se(extract_many_words(&p, NULL, 0, &a, &b, &c, NULL) == 2);
488 assert_se(isempty(p));
489 assert_se(streq_ptr(a, "'foobar'"));
490 assert_se(streq_ptr(b, "wa\"ld\"i"));
491 assert_se(streq_ptr(c, NULL));
495 p = original = "'foobar' wa\"ld\"i ";
496 assert_se(extract_many_words(&p, NULL, EXTRACT_QUOTES, &a, &b, &c, NULL) == 2);
497 assert_se(isempty(p));
498 assert_se(streq_ptr(a, "foobar"));
499 assert_se(streq_ptr(b, "waldi"));
500 assert_se(streq_ptr(c, NULL));
505 assert_se(extract_many_words(&p, NULL, 0, &a, &b, &c, NULL) == 0);
506 assert_se(isempty(p));
507 assert_se(streq_ptr(a, NULL));
508 assert_se(streq_ptr(b, NULL));
509 assert_se(streq_ptr(c, NULL));
512 assert_se(extract_many_words(&p, NULL, 0, &a, &b, &c, NULL) == 0);
513 assert_se(isempty(p));
514 assert_se(streq_ptr(a, NULL));
515 assert_se(streq_ptr(b, NULL));
516 assert_se(streq_ptr(c, NULL));
518 p = original = "foobar";
519 assert_se(extract_many_words(&p, NULL, 0, NULL) == 0);
520 assert_se(p == original);
522 p = original = "foobar waldi";
523 assert_se(extract_many_words(&p, NULL, 0, &a, NULL) == 1);
524 assert_se(p == original+7);
525 assert_se(streq_ptr(a, "foobar"));
528 p = original = " foobar ";
529 assert_se(extract_many_words(&p, NULL, 0, &a, NULL) == 1);
530 assert_se(isempty(p));
531 assert_se(streq_ptr(a, "foobar"));
536 int main(int argc, char *argv[]) {
537 log_parse_environment();
540 test_extract_first_word();
541 #if 0 /// UNNEEDED by elogind
542 test_extract_first_word_and_warn();
543 test_extract_many_words();