]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
shared/fstab-util: teach fstab_filter_options() a mode where all values are returned
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 11 Mar 2021 09:37:36 +0000 (10:37 +0100)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 11 Mar 2021 10:25:15 +0000 (11:25 +0100)
Apart from tests, the new argument isn't used anywhere, so there should be no
functional change. Note that the two arms of the big conditional are switched, so the
diff is artificially inflated. The actual code change is rather small. I dropped the
path which extracts ret_value manually, because it wasn't supporting unescaping of the
escape character properly.

src/core/mount.c
src/cryptsetup/cryptsetup-generator.c
src/fstab-generator/fstab-generator.c
src/shared/fstab-util.c
src/shared/fstab-util.h
src/shared/generator.c
src/test/test-fstab-util.c

index 23b558859c2fef6eb21dea7379b40104c1a235b2..ca5d0939a18f36a5338f284c9876fdad361454a2 100644 (file)
@@ -1019,7 +1019,7 @@ static void mount_enter_mounting(Mount *m) {
         if (p) {
                 _cleanup_free_ char *opts = NULL;
 
-                r = fstab_filter_options(p->options, "nofail\0" "noauto\0" "auto\0", NULL, NULL, &opts);
+                r = fstab_filter_options(p->options, "nofail\0" "noauto\0" "auto\0", NULL, NULL, NULL, &opts);
                 if (r < 0)
                         goto fail;
 
index 74f739b5139e8116833f940cb4cd6f39d5df4a1f..98c8408da54526e45577374ba803f3ed1f6d1e5a 100644 (file)
@@ -301,7 +301,9 @@ static int create_disk(
         netdev = fstab_test_option(options, "_netdev\0");
         attach_in_initrd = fstab_test_option(options, "x-initrd.attach\0");
 
-        keyfile_can_timeout = fstab_filter_options(options, "keyfile-timeout\0", NULL, &keyfile_timeout_value, NULL);
+        keyfile_can_timeout = fstab_filter_options(options,
+                                                   "keyfile-timeout\0",
+                                                   NULL, &keyfile_timeout_value, NULL, NULL);
         if (keyfile_can_timeout < 0)
                 return log_error_errno(keyfile_can_timeout, "Failed to parse keyfile-timeout= option value: %m");
 
@@ -310,11 +312,12 @@ static int create_disk(
                 "header\0",
                 NULL,
                 &header_path,
+                NULL,
                 headerdev ? &filtered_header : NULL);
         if (detached_header < 0)
                 return log_error_errno(detached_header, "Failed to parse header= option value: %m");
 
-        tmp = fstab_filter_options(options, "tmp\0", NULL, &tmp_fstype, NULL);
+        tmp = fstab_filter_options(options, "tmp\0", NULL, &tmp_fstype, NULL, NULL);
         if (tmp < 0)
                 return log_error_errno(tmp, "Failed to parse tmp= option value: %m");
 
@@ -602,7 +605,7 @@ static int filter_header_device(const char *options,
         assert(ret_headerdev);
         assert(ret_filtered_headerdev_options);
 
-        r = fstab_filter_options(options, "header\0", NULL, &headerspec, &filtered_headerspec);
+        r = fstab_filter_options(options, "header\0", NULL, &headerspec, NULL, &filtered_headerspec);
         if (r < 0)
                 return log_error_errno(r, "Failed to parse header= option value: %m");
 
index 7cb4ea286dcc99dac3a4bd15951f2502f61a6221..b454a5980d4b3fe40a1368b08a338f188463a53d 100644 (file)
@@ -200,7 +200,7 @@ static int write_timeout(
         usec_t u;
         int r;
 
-        r = fstab_filter_options(opts, filter, NULL, &timeout, NULL);
+        r = fstab_filter_options(opts, filter, NULL, &timeout, NULL, NULL);
         if (r < 0)
                 return log_warning_errno(r, "Failed to parse options: %m");
         if (r == 0)
index 8dc1733c0de9d811c64911126a86be79264a074a..6674ed4a19f24b644cfe313675b0a97711c3e39a 100644 (file)
@@ -79,21 +79,80 @@ int fstab_is_mount_point(const char *mount) {
         return false;
 }
 
-int fstab_filter_options(const char *opts, const char *names,
-                         const char **ret_namefound, char **ret_value, char **ret_filtered) {
+int fstab_filter_options(
+                const char *opts,
+                const char *names,
+                const char **ret_namefound,
+                char **ret_value,
+                char ***ret_values,
+                char **ret_filtered) {
+
         const char *name, *namefound = NULL, *x;
-        _cleanup_strv_free_ char **stor = NULL;
-        _cleanup_free_ char *v = NULL, **strv = NULL;
+        _cleanup_strv_free_ char **stor = NULL, **values = NULL;
+        _cleanup_free_ char *value = NULL, **filtered = NULL;
         int r;
 
         assert(names && *names);
+        assert(!(ret_value && ret_values));
 
         if (!opts)
                 goto answer;
 
-        /* If !ret_value and !ret_filtered, this function is not allowed to fail. */
+        /* Finds any options matching 'names', and returns:
+         * - the last matching option name in ret_namefound,
+         * - the last matching value in ret_value,
+         * - any matching values in ret_values,
+         * - the rest of the option string in ret_filtered.
+         *
+         * If !ret_value and !ret_values and !ret_filtered, this function is not allowed to fail.
+         *
+         * Returns negative on error, true if any matching options were found, false otherwise. */
+
+        if (ret_filtered || ret_value || ret_values) {
+                /* 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;
+
+                filtered = memdup(stor, sizeof(char*) * (strv_length(stor) + 1));
+                if (!filtered)
+                        return -ENOMEM;
+
+                char **t = filtered;
+                for (char **s = t; *s; s++) {
+                        NULSTR_FOREACH(name, names) {
+                                x = startswith(*s, name);
+                                if (!x)
+                                        continue;
+                                /* Match name, but when ret_values, only when followed by assignment. */
+                                if (*x == '=' || (!ret_values && *x == '\0'))
+                                        goto found;
+                        }
+
+                        *t = *s;
+                        t++;
+                        continue;
+                found:
+                        /* Keep the last occurrence found */
+                        namefound = name;
+
+                        if (ret_value || ret_values) {
+                                assert(IN_SET(*x, '=', '\0'));
 
-        if (!ret_filtered) {
+                                if (ret_value) {
+                                        r = free_and_strdup(&value, *x == '=' ? x + 1 : NULL);
+                                        if (r < 0)
+                                                return r;
+                                } else if (*x) {
+                                        r = strv_extend(&values, x + 1);
+                                        if (r < 0)
+                                                return r;
+                                }
+                        }
+                }
+                *t = NULL;
+        } else
                 for (const char *word = opts;;) {
                         const char *end = word;
 
@@ -121,17 +180,6 @@ int fstab_filter_options(const char *opts, const char *names,
                                 x = word + strlen(name);
                                 if (IN_SET(*x, '\0', '=', ',')) {
                                         namefound = name;
-                                        if (ret_value) {
-                                                bool eq = *x == '=';
-                                                assert(eq || IN_SET(*x, ',', '\0'));
-
-                                                r = free_and_strndup(&v,
-                                                                     eq ? x + 1 : NULL,
-                                                                     eq ? end - x - 1 : 0);
-                                                if (r < 0)
-                                                        return r;
-                                        }
-
                                         break;
                                 }
                         }
@@ -141,40 +189,6 @@ int fstab_filter_options(const char *opts, const char *names,
                         else
                                 break;
                 }
-        } else {
-                /* 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;
-
-                strv = memdup(stor, sizeof(char*) * (strv_length(stor) + 1));
-                if (!strv)
-                        return -ENOMEM;
-
-                char **t = strv;
-                for (char **s = strv; *s; s++) {
-                        NULSTR_FOREACH(name, names) {
-                                x = startswith(*s, name);
-                                if (x && IN_SET(*x, '\0', '='))
-                                        goto found;
-                        }
-
-                        *t = *s;
-                        t++;
-                        continue;
-                found:
-                        /* Keep the last occurrence found */
-                        namefound = name;
-                        if (ret_value) {
-                                assert(IN_SET(*x, '=', '\0'));
-                                r = free_and_strdup(&v, *x == '=' ? x + 1 : NULL);
-                                if (r < 0)
-                                        return r;
-                        }
-                }
-                *t = NULL;
-        }
 
 answer:
         if (ret_namefound)
@@ -182,14 +196,16 @@ answer:
         if (ret_filtered) {
                 char *f;
 
-                f = strv_join_full(strv, ",", NULL, true);
+                f = strv_join_full(filtered, ",", NULL, true);
                 if (!f)
                         return -ENOMEM;
 
                 *ret_filtered = f;
         }
         if (ret_value)
-                *ret_value = TAKE_PTR(v);
+                *ret_value = TAKE_PTR(value);
+        if (ret_values)
+                *ret_values = TAKE_PTR(values);
 
         return !!namefound;
 }
@@ -229,7 +245,7 @@ int fstab_find_pri(const char *options, int *ret) {
 
         assert(ret);
 
-        r = fstab_filter_options(options, "pri\0", NULL, &opt, NULL);
+        r = fstab_filter_options(options, "pri\0", NULL, &opt, NULL, NULL);
         if (r < 0)
                 return r;
         if (r == 0 || !opt)
index 1a602cb56b292fb22945c72dce6e5dadfbcfee77..97f40221afb0037147ea4b93e52ebb37832b7135 100644 (file)
@@ -10,12 +10,18 @@ bool fstab_is_extrinsic(const char *mount, const char *opts);
 int fstab_is_mount_point(const char *mount);
 int fstab_has_fstype(const char *fstype);
 
-int fstab_filter_options(const char *opts, const char *names, const char **namefound, char **value, char **filtered);
+int fstab_filter_options(
+                const char *opts,
+                const char *names,
+                const char **ret_namefound,
+                char **ret_value,
+                char ***ret_values,
+                char **ret_filtered);
 
 int fstab_extract_values(const char *opts, const char *name, char ***values);
 
 static inline bool fstab_test_option(const char *opts, const char *names) {
-        return !!fstab_filter_options(opts, names, NULL, NULL, NULL);
+        return !!fstab_filter_options(opts, names, NULL, NULL, NULL, NULL);
 }
 
 int fstab_find_pri(const char *options, int *ret);
@@ -26,7 +32,7 @@ static inline bool fstab_test_yes_no_option(const char *opts, const char *yes_no
         /* If first name given is last, return 1.
          * If second name given is last or neither is found, return 0. */
 
-        assert_se(fstab_filter_options(opts, yes_no, &opt, NULL, NULL) >= 0);
+        assert_se(fstab_filter_options(opts, yes_no, &opt, NULL, NULL, NULL) >= 0);
 
         return opt == yes_no;
 }
index 41922d67d8c989d07a21b563b0c44cb41ee65e75..5b9c43252714b7b891f88b823af9d82c5f75bd65 100644 (file)
@@ -215,7 +215,7 @@ int generator_write_timeouts(
 
         r = fstab_filter_options(opts, "comment=systemd.device-timeout\0"
                                        "x-systemd.device-timeout\0",
-                                 NULL, &timeout, filtered);
+                                 NULL, &timeout, NULL, filtered);
         if (r < 0) {
                 log_warning_errno(r, "Failed to parse fstab options, ignoring: %m");
                 return 0;
index 3a7ec170d651157a3d47ad9e1f38117eea13b157..d2f201852650d76d6b3db9bde440d660be49fcac 100644 (file)
 #include "fstab-util.h"
 #include "log.h"
 #include "string-util.h"
+#include "strv.h"
 
 /*
-int fstab_filter_options(const char *opts, const char *names,
-                         const char **namefound, char **value, char **filtered);
+int fstab_filter_options(
+        const char *opts,
+        const char *names,
+        const char **ret_namefound,
+        const char **ret_value,
+        const char **ret_values,
+        char **ret_filtered);
 */
 
 static void do_fstab_filter_options(const char *opts,
                                     const char *remove,
                                     int r_expected,
+                                    int r_values_expected,
                                     const char *name_expected,
                                     const char *value_expected,
+                                    const char *values_expected,
                                     const char *filtered_expected) {
         int r;
         const char *name;
-        _cleanup_free_ char *value = NULL, *filtered = NULL;
+        _cleanup_free_ char *value = NULL, *filtered = NULL, *joined = NULL;
+        _cleanup_strv_free_ char **values = NULL;
 
-        r = fstab_filter_options(opts, remove, &name, &value, &filtered);
-        log_info("\"%s\" → %d, \"%s\", \"%s\", \"%s\", expected %d, \"%s\", \"%s\", \"%s\"",
-                 opts, r, name, value, filtered,
+        /* test mode which returns the last value */
+
+        r = fstab_filter_options(opts, remove, &name, &value, NULL, &filtered);
+        log_info("1: \"%s\" → %d, \"%s\", \"%s\", \"%s\", expected %d, \"%s\", \"%s\", \"%s\"",
+                 opts, r, strnull(name), value, filtered,
                  r_expected, name_expected, value_expected, filtered_expected ?: opts);
         assert_se(r == r_expected);
         assert_se(streq_ptr(name, name_expected));
         assert_se(streq_ptr(value, value_expected));
         assert_se(streq_ptr(filtered, filtered_expected ?: opts));
 
+        /* test mode which returns all the values */
+
+        r = fstab_filter_options(opts, remove, &name, NULL, &values, NULL);
+        assert_se(joined = strv_join(values, ":"));
+        log_info("2: \"%s\" → %d, \"%s\", \"%s\", expected %d, \"%s\", \"%s\"",
+                 opts, r, strnull(name), joined,
+                 r_values_expected, name_expected, values_expected);
+        assert_se(r == r_values_expected);
+        assert_se(streq_ptr(name, r_values_expected > 0 ? name_expected : NULL));
+        assert_se(streq_ptr(joined, values_expected));
+
         /* also test the malloc-less mode */
-        r = fstab_filter_options(opts, remove, &name, NULL, NULL);
-        log_info("\"%s\" → %d, \"%s\", expected %d, \"%s\"\n-",
-                 opts, r, name,
+        r = fstab_filter_options(opts, remove, &name, NULL, NULL, NULL);
+        log_info("3: \"%s\" → %d, \"%s\", expected %d, \"%s\"\n-",
+                 opts, r, strnull(name),
                  r_expected, name_expected);
         assert_se(r == r_expected);
         assert_se(streq_ptr(name, name_expected));
 }
 
 static void test_fstab_filter_options(void) {
-        do_fstab_filter_options("opt=0", "opt\0x-opt\0", 1, "opt", "0", "");
-        do_fstab_filter_options("opt=0", "x-opt\0opt\0", 1, "opt", "0", "");
-        do_fstab_filter_options("opt", "opt\0x-opt\0", 1, "opt", NULL, "");
-        do_fstab_filter_options("opt", "x-opt\0opt\0", 1, "opt", NULL, "");
-        do_fstab_filter_options("x-opt", "x-opt\0opt\0", 1, "x-opt", NULL, "");
-
-        do_fstab_filter_options("opt=0,other", "opt\0x-opt\0", 1, "opt", "0", "other");
-        do_fstab_filter_options("opt=0,other", "x-opt\0opt\0", 1, "opt", "0", "other");
-        do_fstab_filter_options("opt,other", "opt\0x-opt\0", 1, "opt", NULL, "other");
-        do_fstab_filter_options("opt,other", "x-opt\0opt\0", 1, "opt", NULL, "other");
-        do_fstab_filter_options("x-opt,other", "opt\0x-opt\0", 1, "x-opt", NULL, "other");
-
-        do_fstab_filter_options("opt=0\\,1,other", "opt\0x-opt\0", 1, "opt", "0,1", "other");
-        do_fstab_filter_options("opt=0,other,x-opt\\,foobar", "x-opt\0opt\0", 1, "opt", "0", "other,x-opt\\,foobar");
-        do_fstab_filter_options("opt,other,x-opt\\,part", "opt\0x-opt\0", 1, "opt", NULL, "other,x-opt\\,part");
-        do_fstab_filter_options("opt,other,part\\,x-opt", "x-opt\0opt\0", 1, "opt", NULL, "other,part\\,x-opt");
-        do_fstab_filter_options("opt,other\\,\\,\\,opt,x-part", "opt\0x-opt\0", 1, "opt", NULL, "other\\,\\,\\,opt,x-part");
-
-        do_fstab_filter_options("opto=0,other", "opt\0x-opt\0", 0, NULL, NULL, NULL);
-        do_fstab_filter_options("opto,other", "opt\0x-opt\0", 0, NULL, NULL, NULL);
-        do_fstab_filter_options("x-opto,other", "opt\0x-opt\0", 0, NULL, NULL, NULL);
-
-        do_fstab_filter_options("first,opt=0", "opt\0x-opt\0", 1, "opt", "0", "first");
-        do_fstab_filter_options("first=1,opt=0", "opt\0x-opt\0", 1, "opt", "0", "first=1");
-        do_fstab_filter_options("first,opt=", "opt\0x-opt\0", 1, "opt", "", "first");
-        do_fstab_filter_options("first=1,opt", "opt\0x-opt\0", 1, "opt", NULL, "first=1");
-        do_fstab_filter_options("first=1,x-opt", "opt\0x-opt\0", 1, "x-opt", NULL, "first=1");
-
-        do_fstab_filter_options("first,opt=0,last=1", "opt\0x-opt\0", 1, "opt", "0", "first,last=1");
-        do_fstab_filter_options("first=1,opt=0,last=2", "x-opt\0opt\0", 1, "opt", "0", "first=1,last=2");
-        do_fstab_filter_options("first,opt,last", "opt\0", 1, "opt", NULL, "first,last");
-        do_fstab_filter_options("first=1,opt,last", "x-opt\0opt\0", 1, "opt", NULL, "first=1,last");
-        do_fstab_filter_options("first=,opt,last", "opt\0noopt\0", 1, "opt", NULL, "first=,last");
+        do_fstab_filter_options("opt=0", "opt\0x-opt\0", 1, 1, "opt", "0", "0", "");
+        do_fstab_filter_options("opt=0", "x-opt\0opt\0", 1, 1, "opt", "0", "0", "");
+        do_fstab_filter_options("opt", "opt\0x-opt\0", 1, 0, "opt", NULL, "", "");
+        do_fstab_filter_options("opt", "x-opt\0opt\0", 1, 0, "opt", NULL, "", "");
+        do_fstab_filter_options("x-opt", "x-opt\0opt\0", 1, 0, "x-opt", NULL, "", "");
+
+        do_fstab_filter_options("opt=0,other", "opt\0x-opt\0", 1, 1, "opt", "0", "0", "other");
+        do_fstab_filter_options("opt=0,other", "x-opt\0opt\0", 1, 1, "opt", "0", "0", "other");
+        do_fstab_filter_options("opt,other", "opt\0x-opt\0", 1, 0, "opt", NULL, "", "other");
+        do_fstab_filter_options("opt,other", "x-opt\0opt\0", 1, 0, "opt", NULL, "", "other");
+        do_fstab_filter_options("x-opt,other", "opt\0x-opt\0", 1, 0, "x-opt", NULL, "", "other");
+
+        do_fstab_filter_options("opt=0\\,1,other", "opt\0x-opt\0", 1, 1, "opt", "0,1", "0,1", "other");
+        do_fstab_filter_options("opt=0,other,x-opt\\,foobar", "x-opt\0opt\0", 1, 1, "opt", "0", "0", "other,x-opt\\,foobar");
+        do_fstab_filter_options("opt,other,x-opt\\,part", "opt\0x-opt\0", 1, 0, "opt", NULL, "", "other,x-opt\\,part");
+        do_fstab_filter_options("opt,other,part\\,x-opt", "x-opt\0opt\0", 1, 0, "opt", NULL, "", "other,part\\,x-opt");
+        do_fstab_filter_options("opt,other\\,\\,\\,opt,x-part", "opt\0x-opt\0", 1, 0, "opt", NULL, "", "other\\,\\,\\,opt,x-part");
+
+        do_fstab_filter_options("opto=0,other", "opt\0x-opt\0", 0, 0, NULL, NULL, "", NULL);
+        do_fstab_filter_options("opto,other", "opt\0x-opt\0", 0, 0, NULL, NULL, "", NULL);
+        do_fstab_filter_options("x-opto,other", "opt\0x-opt\0", 0, 0, NULL, NULL, "", NULL);
+
+        do_fstab_filter_options("first,opt=0", "opt\0x-opt\0", 1, 1, "opt", "0", "0", "first");
+        do_fstab_filter_options("first=1,opt=0", "opt\0x-opt\0", 1, 1, "opt", "0", "0", "first=1");
+        do_fstab_filter_options("first,opt=", "opt\0x-opt\0", 1, 1, "opt", "", "", "first");
+        do_fstab_filter_options("first=1,opt", "opt\0x-opt\0", 1, 0, "opt", NULL, "", "first=1");
+        do_fstab_filter_options("first=1,x-opt", "opt\0x-opt\0", 1, 0, "x-opt", NULL, "", "first=1");
+
+        do_fstab_filter_options("first,opt=0,last=1", "opt\0x-opt\0", 1, 1, "opt", "0", "0", "first,last=1");
+        do_fstab_filter_options("first=1,opt=0,last=2", "x-opt\0opt\0", 1, 1, "opt", "0", "0", "first=1,last=2");
+        do_fstab_filter_options("first,opt,last", "opt\0", 1, 0, "opt", NULL, "", "first,last");
+        do_fstab_filter_options("first=1,opt,last", "x-opt\0opt\0", 1, 0, "opt", NULL, "", "first=1,last");
+        do_fstab_filter_options("first=,opt,last", "opt\0noopt\0", 1, 0, "opt", NULL, "", "first=,last");
 
         /* check repeated options */
-        do_fstab_filter_options("first,opt=0,noopt=1,last=1", "opt\0noopt\0", 1, "noopt", "1", "first,last=1");
-        do_fstab_filter_options("first=1,opt=0,last=2,opt=1", "opt\0", 1, "opt", "1", "first=1,last=2");
-        do_fstab_filter_options("x-opt=0,x-opt=1", "opt\0x-opt\0", 1, "x-opt", "1", "");
-        do_fstab_filter_options("opt=0,x-opt=1", "opt\0x-opt\0", 1, "x-opt", "1", "");
+        do_fstab_filter_options("first,opt=0,noopt=1,last=1", "opt\0noopt\0", 1, 1, "noopt", "1", "0:1", "first,last=1");
+        do_fstab_filter_options("first=1,opt=0,last=2,opt=1", "opt\0", 1, 1, "opt", "1", "0:1", "first=1,last=2");
+        do_fstab_filter_options("x-opt=0,x-opt=1", "opt\0x-opt\0", 1, 1, "x-opt", "1", "0:1", "");
+        do_fstab_filter_options("opt=0,x-opt=1", "opt\0x-opt\0", 1, 1, "x-opt", "1", "0:1", "");
+        do_fstab_filter_options("opt=0,opt=1,opt=,opt=,opt=2", "opt\0noopt\0", 1, 1, "opt", "2", "0:1:::2", "");
 
         /* check that semicolons are not misinterpreted */
-        do_fstab_filter_options("opt=0;", "opt\0", 1, "opt", "0;", "");
-        do_fstab_filter_options("opt;=0", "x-opt\0opt\0noopt\0x-noopt\0", 0, NULL, NULL, NULL);
-        do_fstab_filter_options("opt;", "opt\0x-opt\0", 0, NULL, NULL, NULL);
+        do_fstab_filter_options("opt=0;", "opt\0", 1, 1, "opt", "0;", "0;", "");
+        do_fstab_filter_options("opt;=0", "x-opt\0opt\0noopt\0x-noopt\0", 0, 0, NULL, NULL, "", NULL);
+        do_fstab_filter_options("opt;", "opt\0x-opt\0", 0, 0, NULL, NULL, "", NULL);
 
         /* check that spaces are not misinterpreted */
-        do_fstab_filter_options("opt=0 ", "opt\0", 1, "opt", "0 ", "");
-        do_fstab_filter_options("opt =0", "x-opt\0opt\0noopt\0x-noopt\0", 0, NULL, NULL, NULL);
-        do_fstab_filter_options(" opt ", "opt\0x-opt\0", 0, NULL, NULL, NULL);
+        do_fstab_filter_options("opt=0 ", "opt\0", 1, 1, "opt", "0 ", "0 ", "");
+        do_fstab_filter_options("opt =0", "x-opt\0opt\0noopt\0x-noopt\0", 0, 0, NULL, NULL, "", NULL);
+        do_fstab_filter_options(" opt ", "opt\0x-opt\0", 0, 0, NULL, NULL, "", NULL);
 
         /* check function with NULL args */
-        do_fstab_filter_options(NULL, "opt\0", 0, NULL, NULL, "");
-        do_fstab_filter_options("", "opt\0", 0, NULL, NULL, "");
+        do_fstab_filter_options(NULL, "opt\0", 0, 0, NULL, NULL, "", "");
+        do_fstab_filter_options("", "opt\0", 0, 0, NULL, NULL, "", "");
 
         /* 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", "");
+        do_fstab_filter_options("opt=x,,,,", "opt\0", 1, 1, "opt", "x", "x", "");
+        do_fstab_filter_options(",,,opt=x,,,,", "opt\0", 1, 1, "opt", "x", "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=\\");
+        do_fstab_filter_options("opt1=\\\\,opt2=\\xff", "opt1\0", 1, 1, "opt1", "\\", "\\", "opt2=\\xff");
+        do_fstab_filter_options("opt1=\\\\,opt2=\\xff", "opt2\0", 1, 1, "opt2", "\\xff", "\\xff", "opt1=\\");
 }
 
 static void test_fstab_find_pri(void) {