]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
shared/fstab-util: pass through the escape character
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Wed, 10 Mar 2021 15:53:38 +0000 (16:53 +0100)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 11 Mar 2021 10:25:06 +0000 (11:25 +0100)
… when not used to escape the separator (,) or the escape character (\).
This mostly restores behaviour from before 0645b83a40d1c782f173c4d8440ab2fc82a75006,
but still allows "," to be escaped.

Partially fixes #18952.

src/shared/fstab-util.c
src/test/test-fstab-util.c

index 1ddcd371cfcf590c5b2d2464dc065d8872d38f7b..8dc1733c0de9d811c64911126a86be79264a074a 100644 (file)
@@ -97,16 +97,18 @@ int fstab_filter_options(const char *opts, const char *names,
                 for (const char *word = opts;;) {
                         const char *end = word;
 
-                        /* Look for an *non-escaped* comma separator. Only commas can be escaped, so "\," is
-                         * the only valid escape sequence, so we can do a very simple test here. */
+                        /* Look for a *non-escaped* comma separator. Only commas and backslashes can be
+                         * escaped, so "\," and "\\" are the only valid escape sequences, and we can do a
+                         * very simple test here. */
                         for (;;) {
-                                size_t n = strcspn(end, ",");
+                                end += strcspn(end, ",\\");
 
-                                end += n;
-                                if (n > 0 && end[-1] == '\\')
-                                        end++;
-                                else
+                                if (IN_SET(*end, ',', '\0'))
                                         break;
+                                assert(*end == '\\');
+                                end ++;                 /* Skip the backslash */
+                                if (*end != '\0')
+                                        end ++;         /* Skip the escaped char, but watch out for a trailing commma */
                         }
 
                         NULSTR_FOREACH(name, names) {
@@ -140,7 +142,9 @@ int fstab_filter_options(const char *opts, const char *names,
                                 break;
                 }
         } else {
-                r = strv_split_full(&stor, opts, ",", EXTRACT_UNESCAPE_SEPARATORS);
+                /* For backwards compatibility, we need to pass-through escape characters.
+                 * The only ones we "consume" are the ones used as "\," or "\\". */
+                r = strv_split_full(&stor, opts, ",", EXTRACT_UNESCAPE_SEPARATORS | EXTRACT_UNESCAPE_RELAX);
                 if (r < 0)
                         return r;
 
index ebbdd05ca62d4d6a843c68e64523401f6de7ebad..3a7ec170d651157a3d47ad9e1f38117eea13b157 100644 (file)
@@ -98,6 +98,10 @@ static void test_fstab_filter_options(void) {
         /* unnecessary comma separators */
         do_fstab_filter_options("opt=x,,,,", "opt\0", 1, "opt", "x", "");
         do_fstab_filter_options(",,,opt=x,,,,", "opt\0", 1, "opt", "x", "");
+
+        /* escaped characters */
+        do_fstab_filter_options("opt1=\\\\,opt2=\\xff", "opt1\0", 1, "opt1", "\\", "opt2=\\xff");
+        do_fstab_filter_options("opt1=\\\\,opt2=\\xff", "opt2\0", 1, "opt2", "\\xff", "opt1=\\");
 }
 
 static void test_fstab_find_pri(void) {