Since 044c5d6b "libmultipath: config parser: Allow '"' in strings", double quotes can be part of string values in multipath.conf by escaping them as double-double quotes ('""'). When dumping the configuration, the un-escaping done during config file parsing must be reverted by replacing '"' with '""' again. Signed-off-by: Martin Wilck <mwilck@xxxxxxxx> --- libmultipath/dict.c | 40 ++++++++++++++++++++++++++++++++++++++-- tests/hwtable.c | 18 ------------------ 2 files changed, 38 insertions(+), 20 deletions(-) diff --git a/libmultipath/dict.c b/libmultipath/dict.c index 3e7c5d6d..b5958980 100644 --- a/libmultipath/dict.c +++ b/libmultipath/dict.c @@ -109,9 +109,45 @@ print_nonzero (char *buff, int len, long v) static int print_str (char *buff, int len, const char *ptr) { - if (!ptr) + char *p; + char *last; + const char *q; + + if (!ptr || len <= 0) return 0; - return snprintf(buff, len, "\"%s\"", ptr); + + q = strchr(ptr, '"'); + if (q == NULL) + return snprintf(buff, len, "\"%s\"", ptr); + + last = buff + len - 1; + p = buff; + if (p >= last) + goto out; + *p++ = '"'; + if (p >= last) + goto out; + for (; q; q = strchr(ptr, '"')) { + if (q + 1 - ptr < last - p) + p = mempcpy(p, ptr, q + 1 - ptr); + else { + p = mempcpy(p, ptr, last - p); + goto out; + } + *p++ = '"'; + if (p >= last) + goto out; + ptr = q + 1; + } + p += strlcpy(p, ptr, last - p); + if (p >= last) + goto out; + *p++ = '"'; + *p = '\0'; + return p - buff; +out: + *p = '\0'; + return len; } static int diff --git a/tests/hwtable.c b/tests/hwtable.c index 7daf71eb..9db79391 100644 --- a/tests/hwtable.c +++ b/tests/hwtable.c @@ -598,18 +598,10 @@ static int setup_internal_nvme(void **state) /* * Device section with a simple entry qith double quotes ('foo:"bar"') */ -#if BROKEN -static void test_quoted_hwe(void **state) -#else static void test_quoted_hwe(const struct hwt_state *hwt) -#endif { struct path *pp; -#if BROKEN - struct hwt_state *hwt = CHECK_STATE(state); - _conf = LOAD_CONFIG(hwt); -#endif /* foo:"bar" matches */ pp = mock_path(vnd_foo.value, prd_baq.value); TEST_PROP(prio_name(&pp->prio), prio_emc.value); @@ -625,11 +617,7 @@ static int setup_quoted_hwe(void **state) const struct key_value kv[] = { vnd_foo, prd_baqq, prio_emc }; WRITE_ONE_DEVICE(hwt, kv); -#if BROKEN - condlog(0, "%s: WARNING: skipping conf reload test", __func__); -#else SET_TEST_FUNC(hwt, test_quoted_hwe); -#endif return 0; } @@ -1640,9 +1628,7 @@ static int setup_multipath_config_3(void **state) } define_test(string_hwe) -#if !BROKEN define_test(quoted_hwe) -#endif define_test(internal_nvme) define_test(regex_hwe) define_test(regex_string_hwe) @@ -1680,11 +1666,7 @@ static int test_hwtable(void) cmocka_unit_test(test_sanity_globals), test_entry(internal_nvme), test_entry(string_hwe), -#if BROKEN - cmocka_unit_test_setup(test_quoted_hwe, setup_quoted_hwe), -#else test_entry(quoted_hwe), -#endif test_entry(regex_hwe), test_entry(regex_string_hwe), test_entry(regex_string_hwe_dir), -- 2.17.0 -- dm-devel mailing list dm-devel@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/dm-devel