]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
basic/extract-word: allow escape character to be escaped
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Wed, 10 Mar 2021 14:17:56 +0000 (15:17 +0100)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 11 Mar 2021 08:21:07 +0000 (09:21 +0100)
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.

src/basic/extract-word.c
src/test/test-extract-word.c

index 4e4e7e8ce931b6545e49dc7320accb89208e5626..06b813c031aba5f233f7c2872907ff853d2be6f8 100644 (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++] = '\\';
index f718556d39961c253be9a6c39727f4890c5c668e..217c600dac6cb643bb7e96151b93af3c86e6d128 100644 (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);