summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2015-06-16 14:06:48 +0200
committerThomas Haller <thaller@redhat.com>2015-07-02 15:50:04 +0200
commit7498b670a828d335e177003c9d00d68802f52561 (patch)
treea5736dbdb30440940bdc4f94fe5af79b6e790fb6
parent11c0e107b9b903b13c741448eae68b443e98ad2e (diff)
downloadNetworkManager-7498b670a828d335e177003c9d00d68802f52561.tar.gz
utils: strip whitespace for device spec in nm_match_spec_split()
Via escape sequences, the user still can specify trailing and leading white spaces: such as "\s \s" will result in 3 spaces.
-rw-r--r--src/NetworkManagerUtils.c56
-rw-r--r--src/tests/test-general.c8
2 files changed, 54 insertions, 10 deletions
diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c
index 5a129215f7..24a6f952cb 100644
--- a/src/NetworkManagerUtils.c
+++ b/src/NetworkManagerUtils.c
@@ -1313,11 +1313,32 @@ nm_match_spec_s390_subchannels (const GSList *specs, const char *subchannels)
return match;
}
+/**
+ * nm_match_spec_split:
+ * @value: the string of device specs
+ *
+ * Splits the specs from the string and returns them as individual
+ * entires in a #GSList.
+ *
+ * It does not validate any specs, it basically just does a special
+ * strsplit with ',' or ';' as separators and supporting '\\' as
+ * escape character.
+ *
+ * Leading and trailing spaces of each entry are removed. But the user
+ * can preserve them by specifying "\\s has 2 leading" or "has 2 trailing \\s".
+ *
+ * Specs can have a qualifier like "interface-name:". We still don't strip
+ * any whitespace after the colon, so "interface-name: X" matches an interface
+ * named " X".
+ *
+ * Returns: (transfer-full): the list of device specs.
+ */
GSList *
nm_match_spec_split (const char *value)
{
char *string_value, *p, *q0, *q;
GSList *pieces = NULL;
+ int trailing_ws;
if (!value || !*value)
return NULL;
@@ -1328,7 +1349,13 @@ nm_match_spec_split (const char *value)
string_value = g_new (gchar, strlen (value) + 1);
p = (gchar *) value;
+
+ /* skip over leading whitespace */
+ while (g_ascii_isspace (*p))
+ p++;
+
q0 = q = string_value;
+ trailing_ws = 0;
while (*p) {
if (*p == '\\') {
p++;
@@ -1360,23 +1387,34 @@ nm_match_spec_split (const char *value)
}
break;
}
+ if (*p == '\0')
+ break;
+ p++;
+ trailing_ws = 0;
} else {
*q = *p;
- if (NM_IN_SET (*p, ',', ';')) {
- if (q0 < q)
- pieces = g_slist_prepend (pieces, g_strndup (q0, q - q0));
+ if (*p == '\0')
+ break;
+ if (g_ascii_isspace (*p)) {
+ trailing_ws++;
+ p++;
+ } else if (NM_IN_SET (*p, ',', ';')) {
+ if (q0 < q - trailing_ws)
+ pieces = g_slist_prepend (pieces, g_strndup (q0, (q - q0) - trailing_ws));
q0 = q + 1;
- }
+ p++;
+ trailing_ws = 0;
+ while (g_ascii_isspace (*p))
+ p++;
+ } else
+ p++;
}
- if (*p == '\0')
- break;
q++;
- p++;
}
*q = '\0';
- if (q0 < q)
- pieces = g_slist_prepend (pieces, g_strndup (q0, q - q0));
+ if (q0 < q - trailing_ws)
+ pieces = g_slist_prepend (pieces, g_strndup (q0, (q - q0) - trailing_ws));
g_free (string_value);
return g_slist_reverse (pieces);
}
diff --git a/src/tests/test-general.c b/src/tests/test-general.c
index baea1d54e2..3397dd9715 100644
--- a/src/tests/test-general.c
+++ b/src/tests/test-general.c
@@ -680,6 +680,9 @@ test_match_spec_ifname (const char *spec_str, const char **matches, const char *
g_assert (spec_str);
specs = nm_match_spec_split (spec_str);
+
+ /* also check the matches in the reverse order. They must yield the same result because
+ * matches are inclusive -- except "except:" which always wins. */
specs_reverse = g_slist_reverse (g_slist_copy (specs));
for (i = 0; matches && matches[i]; i++) {
@@ -746,9 +749,12 @@ test_nm_match_spec_interface_name (void)
test_match_spec_ifname ("interface-name:em\\;1,em\\,2,\\,,\\\\,,em\\\\x",
S ("em;1", "em,2", ",", "\\", "em\\x"),
NULL);
- test_match_spec_ifname (" , interface-name:a, ,",
+ test_match_spec_ifname ("\\s\\s,\\sinterface-name:a,\\s,",
S (" ", " ", " interface-name:a"),
NULL);
+ test_match_spec_ifname (" aa ; bb ; cc\\;dd ;e , ; \t\\t , ",
+ S ("aa", "bb", "cc;dd", "e", "\t"),
+ NULL);
#undef S
}