1
0
mirror of https://github.com/systemd/systemd.git synced 2025-03-19 22:50:17 +03:00

basic/extract-word: allow escape character to be escaped

With EXTRACT_UNESCAPE_SEPARATORS, backslash is used to escape the separator.
But it wasn't possible to insert the backslash itself. Let's allow this and
add test.
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2021-03-10 15:17:56 +01:00
parent 8723c716c7
commit 76c4e48ee6
2 changed files with 26 additions and 2 deletions

View File

@ -102,8 +102,8 @@ int extract_first_word(const char **p, char **ret, const char *separators, Extra
else
sz += utf8_encode_unichar(s + sz, u);
} else if ((flags & EXTRACT_UNESCAPE_SEPARATORS) &&
strchr(separators, **p))
/* An escaped separator char */
(strchr(separators, **p) || **p == '\\'))
/* An escaped separator char or the escape char itself */
s[sz++] = c;
else if (flags & EXTRACT_CUNESCAPE_RELAX) {
s[sz++] = '\\';

View File

@ -365,6 +365,18 @@ static void test_extract_first_word(void) {
free(t);
assert_se(p == NULL);
p = "a\\ b:c\\x";
assert_se(extract_first_word(&p, &t, ":", EXTRACT_UNESCAPE_SEPARATORS) == -EINVAL);
p = "a\\\\ b:c\\\\x";
assert_se(extract_first_word(&p, &t, ":", EXTRACT_UNESCAPE_SEPARATORS) == 1);
assert_se(streq(t, "a\\ b"));
free(t);
assert_se(extract_first_word(&p, &t, ":", EXTRACT_UNESCAPE_SEPARATORS) == 1);
assert_se(streq(t, "c\\x"));
free(t);
assert_se(p == NULL);
p = "\\:";
assert_se(extract_first_word(&p, &t, ":", EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS) == 1);
assert_se(streq(t, ":"));
@ -386,6 +398,18 @@ static void test_extract_first_word(void) {
free(t);
assert_se(p == NULL);
p = "a\\ b:c\\x";
assert_se(extract_first_word(&p, &t, ":", EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS) == -EINVAL);
p = "a\\\\ b:c\\\\x";
assert_se(extract_first_word(&p, &t, ":", EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS) == 1);
assert_se(streq(t, "a\\ b"));
free(t);
assert_se(extract_first_word(&p, &t, ":", EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS) == 1);
assert_se(streq(t, "c\\x"));
free(t);
assert_se(p == NULL);
p = "\\:";
assert_se(extract_first_word(&p, &t, ":", EXTRACT_CUNESCAPE) == -EINVAL);