From e26a81cf350d8d43da6a68fde2afcdb48f20f146 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 29 Mar 2017 18:05:00 +0200 Subject: [PATCH] libnm: handler numeric values more gracefully in nm_utils_enum_from_str() nm_utils_enum_to_str() may also output numeric values if there is no corresponding "nick" for the enum/flag value. For enums the value is in decimal and for flags the value is hexadecimal (with a "0x" prefix). The same was already supported by nm_utils_enum_from_str() when reading the value. However, previously, reading a flag would only support hex numbers and reading a enum would only support decimal numbers. Extend that, to allow passing numbers in any base. For nm_utils_enum_to_str() also make sure to never output nicks that may be misinterpreted as numbers. --- libnm-core/nm-utils.c | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index 7fe543d14c..56f9497f2a 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -4260,12 +4260,20 @@ _is_hex_string (const char *str) && NM_STRCHAR_ALL (&str[2], ch, g_ascii_isxdigit (ch)); } +static gboolean +_is_dec_string (const char *str) +{ + return str[0] + && NM_STRCHAR_ALL (&str[0], ch, g_ascii_isdigit (ch)); +} + static gboolean _enum_is_valid_enum_nick (const char *str) { return str[0] && !NM_STRCHAR_ANY (str, ch, g_ascii_isspace (ch)) - && !NM_STRCHAR_ALL (str, ch, g_ascii_isdigit (ch)); + && !_is_dec_string (str) + && !_is_hex_string (str); } static gboolean @@ -4273,6 +4281,7 @@ _enum_is_valid_flags_nick (const char *str) { return str[0] && !NM_STRCHAR_ANY (str, ch, IS_FLAGS_SEPARATOR (ch)) + && !_is_dec_string (str) && !_is_hex_string (str); } @@ -4390,8 +4399,14 @@ nm_utils_enum_from_str (GType type, const char *str, GEnumValue *enum_value; if (s[0]) { - if (NM_STRCHAR_ALL (s, ch, g_ascii_isdigit (ch))) { - v64 = _nm_utils_ascii_str_to_int64 (s, 10, 0, G_MAXINT, -1); + if (_is_hex_string (s)) { + v64 = _nm_utils_ascii_str_to_int64 (s, 16, 0, G_MAXUINT, -1); + if (v64 != -1) { + value = (int) v64; + ret = TRUE; + } + } else if (_is_dec_string (s)) { + v64 = _nm_utils_ascii_str_to_int64 (s, 10, 0, G_MAXUINT, -1); if (v64 != -1) { value = (int) v64; ret = TRUE; @@ -4428,6 +4443,13 @@ nm_utils_enum_from_str (GType type, const char *str, break; } uvalue |= (unsigned) v64; + } else if (_is_dec_string (s)) { + v64 = _nm_utils_ascii_str_to_int64 (s, 10, 0, G_MAXUINT, -1); + if (v64 == -1) { + ret = FALSE; + break; + } + uvalue |= (unsigned) v64; } else { flags_value = g_flags_get_value_by_nick (G_FLAGS_CLASS (class), s); if (!flags_value) {