1 /* SPDX-License-Identifier: LGPL-2.1+ */
7 #include "extract-word.h"
9 #include "string-util.h"
11 static void test_extract_first_word(void) {
12 const char *p, *original;
15 p = original = "foobar waldo";
16 assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
17 assert_se(streq(t, "foobar"));
19 assert_se(p == original + 7);
21 assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
22 assert_se(streq(t, "waldo"));
24 assert_se(isempty(p));
26 assert_se(extract_first_word(&p, &t, NULL, 0) == 0);
28 assert_se(isempty(p));
30 p = original = "\"foobar\" \'waldo\'";
31 assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
32 assert_se(streq(t, "\"foobar\""));
34 assert_se(p == original + 9);
36 assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
37 assert_se(streq(t, "\'waldo\'"));
39 assert_se(isempty(p));
41 assert_se(extract_first_word(&p, &t, NULL, 0) == 0);
43 assert_se(isempty(p));
45 p = original = "\"foobar\" \'waldo\'";
46 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) > 0);
47 assert_se(streq(t, "foobar"));
49 assert_se(p == original + 9);
51 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) > 0);
52 assert_se(streq(t, "waldo"));
54 assert_se(isempty(p));
56 assert_se(extract_first_word(&p, &t, NULL, 0) == 0);
58 assert_se(isempty(p));
61 assert_se(extract_first_word(&p, &t, NULL, 0) == 1);
62 assert_se(streq(t, "\""));
64 assert_se(isempty(p));
67 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) == -EINVAL);
68 assert_se(p == original + 1);
71 assert_se(extract_first_word(&p, &t, NULL, 0) == 1);
72 assert_se(streq(t, "\'"));
74 assert_se(isempty(p));
77 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) == -EINVAL);
78 assert_se(p == original + 1);
80 p = original = "\'fooo";
81 assert_se(extract_first_word(&p, &t, NULL, 0) == 1);
82 assert_se(streq(t, "\'fooo"));
84 assert_se(isempty(p));
86 p = original = "\'fooo";
87 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) == -EINVAL);
88 assert_se(p == original + 5);
90 p = original = "\'fooo";
91 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_RELAX) > 0);
92 assert_se(streq(t, "fooo"));
94 assert_se(isempty(p));
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 = "yay\'foo\'bar";
103 assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
104 assert_se(streq(t, "yay\'foo\'bar"));
106 assert_se(isempty(p));
108 p = original = "yay\'foo\'bar";
109 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) > 0);
110 assert_se(streq(t, "yayfoobar"));
112 assert_se(isempty(p));
114 p = original = " foobar ";
115 assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
116 assert_se(streq(t, "foobar"));
118 assert_se(isempty(p));
120 p = original = " foo\\ba\\x6ar ";
121 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE) > 0);
122 assert_se(streq(t, "foo\ba\x6ar"));
124 assert_se(isempty(p));
126 p = original = " foo\\ba\\x6ar ";
127 assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
128 assert_se(streq(t, "foobax6ar"));
130 assert_se(isempty(p));
132 p = original = " f\\u00f6o \"pi\\U0001F4A9le\" ";
133 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE) > 0);
134 assert_se(streq(t, "föo"));
136 assert_se(p == original + 13);
138 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE) > 0);
139 assert_se(streq(t, "pi\360\237\222\251le"));
141 assert_se(isempty(p));
143 p = original = "fooo\\";
144 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_RELAX) > 0);
145 assert_se(streq(t, "fooo"));
147 assert_se(isempty(p));
149 p = original = "fooo\\";
150 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE_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|EXTRACT_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|EXTRACT_CUNESCAPE_RELAX) > 0);
163 assert_se(streq(t, "fooo\\"));
165 assert_se(isempty(p));
167 p = original = "\"foo\\";
168 assert_se(extract_first_word(&p, &t, NULL, 0) == -EINVAL);
169 assert_se(p == original + 5);
171 p = original = "\"foo\\";
172 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_RELAX) > 0);
173 assert_se(streq(t, "foo"));
175 assert_se(isempty(p));
177 p = original = "foo::bar";
178 assert_se(extract_first_word(&p, &t, ":", 0) == 1);
179 assert_se(streq(t, "foo"));
181 assert_se(p == original + 5);
183 assert_se(extract_first_word(&p, &t, ":", 0) == 1);
184 assert_se(streq(t, "bar"));
186 assert_se(isempty(p));
188 assert_se(extract_first_word(&p, &t, ":", 0) == 0);
190 assert_se(isempty(p));
192 p = original = "foo\\:bar::waldo";
193 assert_se(extract_first_word(&p, &t, ":", 0) == 1);
194 assert_se(streq(t, "foo:bar"));
196 assert_se(p == original + 10);
198 assert_se(extract_first_word(&p, &t, ":", 0) == 1);
199 assert_se(streq(t, "waldo"));
201 assert_se(isempty(p));
203 assert_se(extract_first_word(&p, &t, ":", 0) == 0);
205 assert_se(isempty(p));
207 p = original = "\"foo\\";
208 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE_RELAX) == -EINVAL);
209 assert_se(p == original + 5);
211 p = original = "\"foo\\";
212 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE_RELAX|EXTRACT_RELAX) > 0);
213 assert_se(streq(t, "foo\\"));
215 assert_se(isempty(p));
217 p = original = "\"foo\\";
218 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE|EXTRACT_CUNESCAPE_RELAX|EXTRACT_RELAX) > 0);
219 assert_se(streq(t, "foo\\"));
221 assert_se(isempty(p));
223 p = original = "fooo\\ bar quux";
224 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_RELAX) > 0);
225 assert_se(streq(t, "fooo bar"));
227 assert_se(p == original + 10);
229 p = original = "fooo\\ bar quux";
230 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE_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|EXTRACT_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) == -EINVAL);
243 assert_se(p == original + 5);
245 p = original = "fooo\\ bar quux";
246 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE|EXTRACT_CUNESCAPE_RELAX) > 0);
247 assert_se(streq(t, "fooo\\ bar"));
249 assert_se(p == original + 10);
251 p = original = "\\w+@\\K[\\d.]+";
252 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE) == -EINVAL);
253 assert_se(p == original + 1);
255 p = original = "\\w+@\\K[\\d.]+";
256 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE|EXTRACT_CUNESCAPE_RELAX) > 0);
257 assert_se(streq(t, "\\w+@\\K[\\d.]+"));
259 assert_se(isempty(p));
261 p = original = "\\w+\\b";
262 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE|EXTRACT_CUNESCAPE_RELAX) > 0);
263 assert_se(streq(t, "\\w+\b"));
265 assert_se(isempty(p));
267 p = original = "-N ''";
268 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) > 0);
269 assert_se(streq(t, "-N"));
271 assert_se(p == original + 3);
273 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) > 0);
274 assert_se(streq(t, ""));
276 assert_se(isempty(p));
278 p = original = ":foo\\:bar::waldo:";
279 assert_se(extract_first_word(&p, &t, ":", EXTRACT_DONT_COALESCE_SEPARATORS) == 1);
281 assert_se(streq(t, ""));
283 assert_se(p == original + 1);
285 assert_se(extract_first_word(&p, &t, ":", EXTRACT_DONT_COALESCE_SEPARATORS) == 1);
286 assert_se(streq(t, "foo:bar"));
288 assert_se(p == original + 10);
290 assert_se(extract_first_word(&p, &t, ":", EXTRACT_DONT_COALESCE_SEPARATORS) == 1);
292 assert_se(streq(t, ""));
294 assert_se(p == original + 11);
296 assert_se(extract_first_word(&p, &t, ":", EXTRACT_DONT_COALESCE_SEPARATORS) == 1);
297 assert_se(streq(t, "waldo"));
299 assert_se(p == original + 17);
301 assert_se(extract_first_word(&p, &t, ":", EXTRACT_DONT_COALESCE_SEPARATORS) == 1);
302 assert_se(streq(t, ""));
304 assert_se(p == NULL);
306 assert_se(extract_first_word(&p, &t, ":", EXTRACT_DONT_COALESCE_SEPARATORS) == 0);
311 assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
312 assert_se(streq(t, "fooxbar"));
314 assert_se(p == NULL);
317 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_RETAIN_ESCAPE) > 0);
318 assert_se(streq(t, "foo\\xbar"));
320 assert_se(p == NULL);
323 #if 0 /// UNNEEDED by elogind
324 static void test_extract_first_word_and_warn(void) {
325 const char *p, *original;
328 p = original = "foobar waldo";
329 assert_se(extract_first_word_and_warn(&p, &t, NULL, 0, NULL, "fake", 1, original) > 0);
330 assert_se(streq(t, "foobar"));
332 assert_se(p == original + 7);
334 assert_se(extract_first_word_and_warn(&p, &t, NULL, 0, NULL, "fake", 1, original) > 0);
335 assert_se(streq(t, "waldo"));
337 assert_se(isempty(p));
339 assert_se(extract_first_word_and_warn(&p, &t, NULL, 0, NULL, "fake", 1, original) == 0);
341 assert_se(isempty(p));
343 p = original = "\"foobar\" \'waldo\'";
344 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES, NULL, "fake", 1, original) > 0);
345 assert_se(streq(t, "foobar"));
347 assert_se(p == original + 9);
349 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES, NULL, "fake", 1, original) > 0);
350 assert_se(streq(t, "waldo"));
352 assert_se(isempty(p));
354 assert_se(extract_first_word_and_warn(&p, &t, NULL, 0, NULL, "fake", 1, original) == 0);
356 assert_se(isempty(p));
359 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES, NULL, "fake", 1, original) == -EINVAL);
360 assert_se(p == original + 1);
363 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES, NULL, "fake", 1, original) == -EINVAL);
364 assert_se(p == original + 1);
366 p = original = "\'fooo";
367 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES, NULL, "fake", 1, original) == -EINVAL);
368 assert_se(p == original + 5);
370 p = original = "\'fooo";
371 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_RELAX, NULL, "fake", 1, original) > 0);
372 assert_se(streq(t, "fooo"));
374 assert_se(isempty(p));
376 p = original = " foo\\ba\\x6ar ";
377 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_CUNESCAPE, NULL, "fake", 1, original) > 0);
378 assert_se(streq(t, "foo\ba\x6ar"));
380 assert_se(isempty(p));
382 p = original = " foo\\ba\\x6ar ";
383 assert_se(extract_first_word_and_warn(&p, &t, NULL, 0, NULL, "fake", 1, original) > 0);
384 assert_se(streq(t, "foobax6ar"));
386 assert_se(isempty(p));
388 p = original = " f\\u00f6o \"pi\\U0001F4A9le\" ";
389 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_CUNESCAPE, NULL, "fake", 1, original) > 0);
390 assert_se(streq(t, "föo"));
392 assert_se(p == original + 13);
394 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE, NULL, "fake", 1, original) > 0);
395 assert_se(streq(t, "pi\360\237\222\251le"));
397 assert_se(isempty(p));
399 p = original = "fooo\\";
400 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_RELAX, NULL, "fake", 1, original) > 0);
401 assert_se(streq(t, "fooo"));
403 assert_se(isempty(p));
405 p = original = "fooo\\";
406 assert_se(extract_first_word_and_warn(&p, &t, NULL, 0, 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, EXTRACT_CUNESCAPE, NULL, "fake", 1, original) > 0);
413 assert_se(streq(t, "fooo\\"));
415 assert_se(isempty(p));
417 p = original = "\"foo\\";
418 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES, NULL, "fake", 1, original) == -EINVAL);
419 assert_se(p == original + 5);
421 p = original = "\"foo\\";
422 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_RELAX, NULL, "fake", 1, original) > 0);
423 assert_se(streq(t, "foo"));
425 assert_se(isempty(p));
427 p = original = "\"foo\\";
428 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE, NULL, "fake", 1, original) == -EINVAL);
429 assert_se(p == original + 5);
431 p = original = "\"foo\\";
432 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE|EXTRACT_RELAX, NULL, "fake", 1, original) > 0);
433 assert_se(streq(t, "foo"));
435 assert_se(isempty(p));
437 p = original = "fooo\\ bar quux";
438 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_RELAX, NULL, "fake", 1, original) > 0);
439 assert_se(streq(t, "fooo bar"));
441 assert_se(p == original + 10);
443 p = original = "fooo\\ bar quux";
444 assert_se(extract_first_word_and_warn(&p, &t, NULL, 0, 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, EXTRACT_CUNESCAPE, NULL, "fake", 1, original) > 0);
451 assert_se(streq(t, "fooo\\ bar"));
453 assert_se(p == original + 10);
455 p = original = "\\w+@\\K[\\d.]+";
456 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_CUNESCAPE, NULL, "fake", 1, original) > 0);
457 assert_se(streq(t, "\\w+@\\K[\\d.]+"));
459 assert_se(isempty(p));
461 p = original = "\\w+\\b";
462 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_CUNESCAPE, NULL, "fake", 1, original) > 0);
463 assert_se(streq(t, "\\w+\b"));
465 assert_se(isempty(p));
468 static void test_extract_many_words(void) {
469 const char *p, *original;
472 p = original = "foobar waldi piep";
473 assert_se(extract_many_words(&p, NULL, 0, &a, &b, &c, NULL) == 3);
474 assert_se(isempty(p));
475 assert_se(streq_ptr(a, "foobar"));
476 assert_se(streq_ptr(b, "waldi"));
477 assert_se(streq_ptr(c, "piep"));
482 p = original = "'foobar' wa\"ld\"i ";
483 assert_se(extract_many_words(&p, NULL, 0, &a, &b, &c, NULL) == 2);
484 assert_se(isempty(p));
485 assert_se(streq_ptr(a, "'foobar'"));
486 assert_se(streq_ptr(b, "wa\"ld\"i"));
487 assert_se(streq_ptr(c, NULL));
491 p = original = "'foobar' wa\"ld\"i ";
492 assert_se(extract_many_words(&p, NULL, EXTRACT_QUOTES, &a, &b, &c, NULL) == 2);
493 assert_se(isempty(p));
494 assert_se(streq_ptr(a, "foobar"));
495 assert_se(streq_ptr(b, "waldi"));
496 assert_se(streq_ptr(c, NULL));
501 assert_se(extract_many_words(&p, NULL, 0, &a, &b, &c, NULL) == 0);
502 assert_se(isempty(p));
503 assert_se(streq_ptr(a, NULL));
504 assert_se(streq_ptr(b, NULL));
505 assert_se(streq_ptr(c, NULL));
508 assert_se(extract_many_words(&p, NULL, 0, &a, &b, &c, NULL) == 0);
509 assert_se(isempty(p));
510 assert_se(streq_ptr(a, NULL));
511 assert_se(streq_ptr(b, NULL));
512 assert_se(streq_ptr(c, NULL));
514 p = original = "foobar";
515 assert_se(extract_many_words(&p, NULL, 0, NULL) == 0);
516 assert_se(p == original);
518 p = original = "foobar waldi";
519 assert_se(extract_many_words(&p, NULL, 0, &a, NULL) == 1);
520 assert_se(p == original+7);
521 assert_se(streq_ptr(a, "foobar"));
524 p = original = " foobar ";
525 assert_se(extract_many_words(&p, NULL, 0, &a, NULL) == 1);
526 assert_se(isempty(p));
527 assert_se(streq_ptr(a, "foobar"));
532 int main(int argc, char *argv[]) {
533 log_parse_environment();
536 test_extract_first_word();
537 #if 0 /// UNNEEDED by elogind
538 test_extract_first_word_and_warn();
539 test_extract_many_words();