mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-01-20 14:03:39 +03:00
util: Allow non-separator coalescing parsing in extract_first_word
If EXTRACT_DONT_COALESCE_SEPARATORS is passed, then leading separators, trailing separators and spans of multiple separators aren't skipped, and empty arguments from before, after or between separators may be extracted.
This commit is contained in:
parent
12ba2c44dd
commit
206644aede
@ -5735,10 +5735,20 @@ int extract_first_word(const char **p, char **ret, const char *separators, Extra
|
||||
switch (state) {
|
||||
|
||||
case START:
|
||||
if (c == 0)
|
||||
if (c == 0) {
|
||||
if (flags & EXTRACT_DONT_COALESCE_SEPARATORS)
|
||||
if (!GREEDY_REALLOC(s, allocated, sz+1))
|
||||
return -ENOMEM;
|
||||
goto finish_force_terminate;
|
||||
else if (strchr(separators, c))
|
||||
} else if (strchr(separators, c)) {
|
||||
if (flags & EXTRACT_DONT_COALESCE_SEPARATORS) {
|
||||
if (!GREEDY_REALLOC(s, allocated, sz+1))
|
||||
return -ENOMEM;
|
||||
(*p) ++;
|
||||
goto finish_force_next;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
state = VALUE;
|
||||
/* fallthrough */
|
||||
@ -5758,9 +5768,13 @@ int extract_first_word(const char **p, char **ret, const char *separators, Extra
|
||||
return -ENOMEM;
|
||||
|
||||
state = DOUBLE_QUOTE;
|
||||
} else if (strchr(separators, c))
|
||||
} else if (strchr(separators, c)) {
|
||||
if (flags & EXTRACT_DONT_COALESCE_SEPARATORS) {
|
||||
(*p) ++;
|
||||
goto finish_force_next;
|
||||
}
|
||||
state = SEPARATOR;
|
||||
else {
|
||||
} else {
|
||||
if (!GREEDY_REALLOC(s, allocated, sz+2))
|
||||
return -ENOMEM;
|
||||
|
||||
@ -5857,10 +5871,11 @@ end_escape:
|
||||
|
||||
case SEPARATOR:
|
||||
if (c == 0)
|
||||
goto finish;
|
||||
goto finish_force_terminate;
|
||||
if (flags & EXTRACT_DONT_COALESCE_SEPARATORS)
|
||||
goto finish_force_next;
|
||||
if (!strchr(separators, c))
|
||||
goto finish;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -5876,6 +5891,7 @@ finish:
|
||||
return 0;
|
||||
}
|
||||
|
||||
finish_force_next:
|
||||
s[sz] = 0;
|
||||
*ret = s;
|
||||
s = NULL;
|
||||
|
@ -859,6 +859,7 @@ typedef enum ExtractFlags {
|
||||
EXTRACT_CUNESCAPE = 2,
|
||||
EXTRACT_CUNESCAPE_RELAX = 4,
|
||||
EXTRACT_QUOTES = 8,
|
||||
EXTRACT_DONT_COALESCE_SEPARATORS = 16,
|
||||
} ExtractFlags;
|
||||
|
||||
int extract_first_word(const char **p, char **ret, const char *separators, ExtractFlags flags);
|
||||
|
@ -1744,6 +1744,38 @@ static void test_extract_first_word(void) {
|
||||
assert_se(streq(t, ""));
|
||||
free(t);
|
||||
assert_se(isempty(p));
|
||||
|
||||
p = original = ":foo\\:bar::waldo:";
|
||||
assert_se(extract_first_word(&p, &t, ":", EXTRACT_DONT_COALESCE_SEPARATORS) == 1);
|
||||
assert_se(t);
|
||||
assert_se(streq(t, ""));
|
||||
free(t);
|
||||
assert_se(p == original + 1);
|
||||
|
||||
assert_se(extract_first_word(&p, &t, ":", EXTRACT_DONT_COALESCE_SEPARATORS) == 1);
|
||||
assert_se(streq(t, "foo:bar"));
|
||||
free(t);
|
||||
assert_se(p == original + 10);
|
||||
|
||||
assert_se(extract_first_word(&p, &t, ":", EXTRACT_DONT_COALESCE_SEPARATORS) == 1);
|
||||
assert_se(t);
|
||||
assert_se(streq(t, ""));
|
||||
free(t);
|
||||
assert_se(p == original + 11);
|
||||
|
||||
assert_se(extract_first_word(&p, &t, ":", EXTRACT_DONT_COALESCE_SEPARATORS) == 1);
|
||||
assert_se(streq(t, "waldo"));
|
||||
free(t);
|
||||
assert_se(p == original + 17);
|
||||
|
||||
assert_se(extract_first_word(&p, &t, ":", EXTRACT_DONT_COALESCE_SEPARATORS) == 1);
|
||||
assert_se(streq(t, ""));
|
||||
free(t);
|
||||
assert_se(p == NULL);
|
||||
|
||||
assert_se(extract_first_word(&p, &t, ":", EXTRACT_DONT_COALESCE_SEPARATORS) == 0);
|
||||
assert_se(!t);
|
||||
assert_se(!p);
|
||||
}
|
||||
|
||||
static void test_extract_first_word_and_warn(void) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user