diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index 664d596733..1009908ba4 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -3229,7 +3229,7 @@ _set_fcn_match_interface_name (ARGS_SET_FCN) if (strv) { for (i = 0; strv[i]; i++) { nm_setting_match_add_interface_name (NM_SETTING_MATCH (setting), - _nm_utils_unescape_spaces ((char *) strv[i])); + _nm_utils_unescape_spaces ((char *) strv[i], TRUE)); } } return TRUE; diff --git a/libnm-core/tests/test-general.c b/libnm-core/tests/test-general.c index 9fcf7d006c..876e48388a 100644 --- a/libnm-core/tests/test-general.c +++ b/libnm-core/tests/test-general.c @@ -7733,24 +7733,73 @@ test_nm_utils_escape_spaces (void) g_free (to_free); } +static void +_do_test_unescape_spaces (const char *in, const char *out) +{ + nm_auto_free_gstring GString *str_out = g_string_new (NULL); + nm_auto_free_gstring GString *str_in = g_string_new (NULL); + guint i; + + for (i = 0; i < 10; i++) { + + g_string_set_size (str_in, 0); + + g_string_append (str_in, in); + + if (i == 0) + g_assert_cmpstr (_nm_utils_unescape_spaces (str_in->str, FALSE), ==, out); + else if (i == 1) + g_assert_cmpstr (_nm_utils_unescape_spaces (str_in->str, TRUE), ==, out); + else { + bool do_strip = nmtst_get_rand_bool (); + guint n = nmtst_get_rand_int () % 20; + guint j; + + g_string_set_size (str_out, 0); + if (!do_strip) + g_string_append (str_out, out); + + for (j = 0; j < n; j++) { + gboolean append = nmtst_get_rand_bool (); + char ch = nmtst_rand_select (' ', '\t'); + + if (append && out[strlen (out) - 1] == '\\') + append = FALSE; + + g_string_insert_c (str_in, append ? -1 : 0, ch); + if (!do_strip) + g_string_insert_c (str_out, append ? -1 : 0, ch); + } + + if (do_strip) + g_assert_cmpstr (_nm_utils_unescape_spaces (str_in->str, TRUE), ==, out); + else + g_assert_cmpstr (_nm_utils_unescape_spaces (str_in->str, FALSE), ==, str_out->str); + } + } +} + static void test_nm_utils_unescape_spaces (void) { -#define CHECK_STR(in, out) \ - G_STMT_START { \ - gs_free char *str = g_strdup (in); \ - \ - g_assert_cmpstr (_nm_utils_unescape_spaces (str), ==, out); \ - } G_STMT_END - - CHECK_STR ("\\a", "\\a"); - CHECK_STR ("foobar", "foobar"); - CHECK_STR ("foo bar", "foo bar"); - CHECK_STR ("foo\\ bar", "foo bar"); - CHECK_STR ("foo\\", "foo\\"); - CHECK_STR ("\\\\\t", "\\\t"); - -#undef CHECK_STR + _do_test_unescape_spaces ("", ""); + _do_test_unescape_spaces ("\\", "\\"); + _do_test_unescape_spaces ("\\ ", " "); + _do_test_unescape_spaces ("\\\t", "\t"); + _do_test_unescape_spaces ("a", "a"); + _do_test_unescape_spaces ("\\a", "\\a"); + _do_test_unescape_spaces ("foobar", "foobar"); + _do_test_unescape_spaces ("foo bar", "foo bar"); + _do_test_unescape_spaces ("foo\\ bar", "foo bar"); + _do_test_unescape_spaces ("foo\\", "foo\\"); + _do_test_unescape_spaces ("\\\\", "\\\\"); + _do_test_unescape_spaces ("foo bar", "foo bar"); + _do_test_unescape_spaces ("\\ foo bar", " foo bar"); + _do_test_unescape_spaces ("\\ foo bar\\ ", " foo bar "); + _do_test_unescape_spaces ("\\\tfoo bar\\\t", "\tfoo bar\t"); + _do_test_unescape_spaces ("\\\tfoo bar \\\t", "\tfoo bar \t"); + _do_test_unescape_spaces ("\\\t", "\t"); + _do_test_unescape_spaces ("\\\t \\ ", "\t "); } /*****************************************************************************/ diff --git a/shared/nm-utils/nm-shared-utils.c b/shared/nm-utils/nm-shared-utils.c index ae6262143c..7789034de5 100644 --- a/shared/nm-utils/nm-shared-utils.c +++ b/shared/nm-utils/nm-shared-utils.c @@ -2458,20 +2458,36 @@ _nm_utils_escape_spaces (const char *str, char **to_free) } char * -_nm_utils_unescape_spaces (char *str) +_nm_utils_unescape_spaces (char *str, gboolean do_strip) { - guint i, j = 0; + gsize i = 0; + gsize j = 0; + gsize preserve_space_at = 0; if (!str) return NULL; - for (i = 0; str[i]; i++) { - if (str[i] == '\\' && IS_SPACE (str[i+1])) + if (do_strip) { + while (str[i] && IS_SPACE (str[i])) i++; + } + + for (; str[i]; i++) { + if ( str[i] == '\\' + && IS_SPACE (str[i+1])) { + preserve_space_at = j; + i++; + } str[j++] = str[i]; } str[j] = '\0'; + if (do_strip && j > 0) { + while ( --j > preserve_space_at + && IS_SPACE (str[j])) + str[j] = '\0'; + } + return str; } diff --git a/shared/nm-utils/nm-shared-utils.h b/shared/nm-utils/nm-shared-utils.h index 51e57ee03f..6ed1bc574e 100644 --- a/shared/nm-utils/nm-shared-utils.h +++ b/shared/nm-utils/nm-shared-utils.h @@ -1085,7 +1085,7 @@ void _nm_utils_user_data_unpack (gpointer user_data, int nargs, ...); /*****************************************************************************/ const char *_nm_utils_escape_spaces (const char *str, char **to_free); -char *_nm_utils_unescape_spaces (char *str); +char *_nm_utils_unescape_spaces (char *str, gboolean do_strip); /*****************************************************************************/ diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c index 03d2cb6330..7779319b7f 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c @@ -1449,7 +1449,7 @@ make_match_setting (shvarFile *ifcfg) if (!s_match) s_match = (NMSettingMatch *) nm_setting_match_new (); nm_setting_match_add_interface_name (s_match, - _nm_utils_unescape_spaces ((char *) strv[i])); + _nm_utils_unescape_spaces ((char *) strv[i], TRUE)); } }