_cleanup_free_ char *word = NULL;
int r;
- r = extract_first_word(&options, &word, ",", EXTRACT_DONT_COALESCE_SEPARATORS);
+ r = extract_first_word(&options, &word, ",", EXTRACT_DONT_COALESCE_SEPARATORS | EXTRACT_UNESCAPE_SEPARATORS);
if (r < 0)
return log_error_errno(r, "Failed to parse options: %m");
if (r == 0)
return r;
}
+ log_debug("%s %s ← %s type=%s cipher=%s", __func__,
+ argv[2], argv[3], strempty(arg_type), strempty(arg_cipher));
+
/* A delicious drop of snake oil */
(void) mlockall(MCL_FUTURE);
if (!ret_filtered) {
for (const char *word = opts;;) {
- const char *end = word + strcspn(word, ",");
+ 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. */
+ for (;;) {
+ size_t n = strcspn(end, ",");
+
+ end += n;
+ if (n > 0 && end[-1] == '\\')
+ end++;
+ else
+ break;
+ }
NULSTR_FOREACH(name, names) {
if (end < word + strlen(name))
break;
}
} else {
- stor = strv_split(opts, ",");
- if (!stor)
- return -ENOMEM;
+ r = strv_split_full(&stor, opts, ",", EXTRACT_DONT_COALESCE_SEPARATORS | EXTRACT_UNESCAPE_SEPARATORS);
+ if (r < 0)
+ return r;
+
strv = memdup(stor, sizeof(char*) * (strv_length(stor) + 1));
if (!strv)
return -ENOMEM;
if (ret_filtered) {
char *f;
- f = strv_join(strv, ",");
+ f = strv_join_full(strv, ",", NULL, true);
if (!f)
return -ENOMEM;
*/
static void do_fstab_filter_options(const char *opts,
- const char *remove,
- int r_expected,
- const char *name_expected,
- const char *value_expected,
- const char *filtered_expected) {
-
+ const char *remove,
+ int r_expected,
+ const char *name_expected,
+ const char *value_expected,
+ const char *filtered_expected) {
int r;
const char *name;
_cleanup_free_ char *value = NULL, *filtered = NULL;
/* also test the malloc-less mode */
r = fstab_filter_options(opts, remove, &name, NULL, NULL);
- log_info("\"%s\" → %d, \"%s\", expected %d, \"%s\"",
+ log_info("\"%s\" → %d, \"%s\", expected %d, \"%s\"\n-",
opts, r, name,
r_expected, name_expected);
assert_se(r == r_expected);
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);