From: Zbigniew Jędrzejewski-Szmek Date: Wed, 10 Mar 2021 14:17:56 +0000 (+0100) Subject: basic/extract-word: allow escape character to be escaped X-Git-Tag: v248-rc3~2^2~4 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=76c4e48ee603593822b3076c4cf5b63768ec55e3;p=thirdparty%2Fsystemd.git 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. --- diff --git a/src/basic/extract-word.c b/src/basic/extract-word.c index 4e4e7e8ce93..06b813c031a 100644 --- a/src/basic/extract-word.c +++ b/src/basic/extract-word.c @@ -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++] = '\\'; diff --git a/src/test/test-extract-word.c b/src/test/test-extract-word.c index f718556d399..217c600dac6 100644 --- a/src/test/test-extract-word.c +++ b/src/test/test-extract-word.c @@ -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);