summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2017-01-25 16:07:36 +0100
committerThomas Haller <thaller@redhat.com>2017-01-25 17:15:23 +0100
commit419151a19ec494d1db3309d47d6ee60856f751d6 (patch)
treeeb6dff9360646d969574754a2f6759afe249c68e
parent0f7098b71bbfc6024b0f39ce858448d928af6ae5 (diff)
downloadNetworkManager-419151a19ec494d1db3309d47d6ee60856f751d6.tar.gz
core: refactor parsing in match_device_s390_subchannels_parse()
Changes: - match_device_s390_subchannels_parse() should accept un-initialized arguments a,b,c, as they are striclty output arguments (without transfering ownership). - the output arguments should be set if (and only if) the function succeeds. That is, move assigning the output arguments to the end. - increase the BUFSIZE. It's unclear why choosing 10. Probably that was already sufficient as a subchannel looks like "0.0.f5f0,0.0.f5f1,0.0.f5f2". Still, increase it to be ample. If we want to restrict the parsing based on the lenght of the input, that should be done explicitly (but that seems not desirable). - use _nm_utils_ascii_str_to_int64() which checks that the range of the values fits in guint32. It seems wrong that match_device_s390_subchannels_eval() only compares the first of up to three subchannels. But leave it as is for now.
-rw-r--r--src/nm-core-utils.c67
1 files changed, 32 insertions, 35 deletions
diff --git a/src/nm-core-utils.c b/src/nm-core-utils.c
index 1501ef984e..631540a17c 100644
--- a/src/nm-core-utils.c
+++ b/src/nm-core-utils.c
@@ -1232,67 +1232,64 @@ typedef struct {
} MatchDeviceData;
static gboolean
-match_device_s390_subchannels_parse (const char *s390_subchannels, guint32 *a, guint32 *b, guint32 *c)
+match_device_s390_subchannels_parse (const char *s390_subchannels, guint32 *out_a, guint32 *out_b, guint32 *out_c)
{
- const int BUFSIZE = 10;
- long unsigned int tmp;
+ const int BUFSIZE = 30;
char buf[BUFSIZE + 1];
- const char *p = s390_subchannels;
- int i = 0;
+ guint i = 0;
char *pa = NULL, *pb = NULL, *pc = NULL;
+ gint64 a, b, c;
nm_assert (s390_subchannels);
- nm_assert (a != NULL);
- nm_assert (*a == 0);
- nm_assert (b != NULL);
- nm_assert (*b == 0);
- nm_assert (c != NULL);
- nm_assert (*c == 0);
-
- /* sanity check */
+ nm_assert (out_a);
+ nm_assert (out_b);
+ nm_assert (out_c);
+
if (!g_ascii_isxdigit (s390_subchannels[0]))
return FALSE;
/* Get the first channel */
- while (*p && (*p != ',')) {
- if (!g_ascii_isxdigit (*p) && (*p != '.'))
+ for (i = 0; s390_subchannels[i]; i++) {
+ char ch = s390_subchannels[i];
+
+ if (!g_ascii_isxdigit (ch) && ch != '.') {
+ if (ch == ',') {
+ /* FIXME: currently we consider the first channel and ignore
+ * everything after the first ',' separator. Maybe we should
+ * validate all present channels? */
+ break;
+ }
return FALSE; /* Invalid chars */
+ }
if (i >= BUFSIZE)
return FALSE; /* Too long to be a subchannel */
- buf[i++] = *p++;
+ buf[i] = ch;
}
buf[i] = '\0';
/* and grab each of its elements, there should be 3 */
pa = &buf[0];
- pb = strchr (buf, '.');
+ pb = strchr (pa, '.');
if (pb)
pc = strchr (pb + 1, '.');
- if (!pa || !pb || !pc)
+ if (!pb || !pc)
return FALSE;
-
- /* Split the string */
*pb++ = '\0';
*pc++ = '\0';
- errno = 0;
- tmp = strtoul (pa, NULL, 16);
- if (errno)
+ a = _nm_utils_ascii_str_to_int64 (pa, 16, 0, G_MAXUINT32, -1);
+ if (a == -1)
return FALSE;
- *a = (guint32) tmp;
-
- errno = 0;
- tmp = strtoul (pb, NULL, 16);
- if (errno)
+ b = _nm_utils_ascii_str_to_int64 (pb, 16, 0, G_MAXUINT32, -1);
+ if (b == -1)
return FALSE;
- *b = (guint32) tmp;
-
- errno = 0;
- tmp = strtoul (pc, NULL, 16);
- if (errno)
+ c = _nm_utils_ascii_str_to_int64 (pc, 16, 0, G_MAXUINT32, -1);
+ if (c == -1)
return FALSE;
- *c = (guint32) tmp;
+ *out_a = (guint32) a;
+ *out_b = (guint32) b;
+ *out_c = (guint32) c;
return TRUE;
}
@@ -1300,7 +1297,7 @@ static gboolean
match_data_s390_subchannels_eval (const char *spec_str,
MatchDeviceData *match_data)
{
- guint32 a = 0, b = 0, c = 0;
+ guint32 a, b, c;
if (G_UNLIKELY (!match_data->s390_subchannels.is_parsed)) {
match_data->s390_subchannels.is_parsed = TRUE;