diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index e5fd8d181c..d25aa45245 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -2279,21 +2279,42 @@ _nm_utils_string_append_tc_parent (GString *string, const char *prefix, guint32 guint32 _nm_utils_parse_tc_handle (const char *str, GError **error) { - gint64 maj, min; - char *sep; + gint64 maj; + gint64 min = 0; + const char *sep; - maj = g_ascii_strtoll (str, &sep, 0x10); - if (*sep == ':') - min = g_ascii_strtoll (&sep[1], &sep, 0x10); - else - min = 0; + nm_assert (str); - if (*sep != '\0' || maj <= 0 || maj > 0xffff || min < 0 || min > 0xffff) { - g_set_error (error, 1, 0, _("'%s' is not a valid handle."), str); - return TC_H_UNSPEC; + maj = g_ascii_strtoll (str, (char **) &sep, 0x10); + if (sep == str) + goto fail; + + sep = nm_str_skip_leading_spaces (sep); + + if (sep[0] == ':') { + const char *str2 = &sep[1]; + + min = g_ascii_strtoll (str2, (char **) &sep, 0x10); + sep = nm_str_skip_leading_spaces (sep); + if (sep[0] != '\0') + goto fail; + } else if (sep[0] != '\0') + goto fail; + + if ( maj <= 0 + || maj > 0xffff + || min < 0 + || min > 0xffff + || !NM_STRCHAR_ALL (str, ch, ( g_ascii_isxdigit (ch) + || ch == ':' + || g_ascii_isspace (ch)))) { + goto fail; } - return TC_H_MAKE (maj << 16, min); + return TC_H_MAKE (((guint32) maj) << 16, (guint32) min); +fail: + nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN, _("'%s' is not a valid handle."), str); + return TC_H_UNSPEC; } #define TC_ATTR_SPEC_PTR(name, type, no_value, consumes_rest, str_type) \ diff --git a/libnm-core/tests/test-setting.c b/libnm-core/tests/test-setting.c index 8bb6f04dee..5b2c323df4 100644 --- a/libnm-core/tests/test-setting.c +++ b/libnm-core/tests/test-setting.c @@ -3117,27 +3117,27 @@ test_parse_tc_handle (void) _parse_tc_handle_inval (" "); _parse_tc_handle_inval (" \n"); _parse_tc_handle_valid ("1", 1, 0); - _parse_tc_handle_inval(" 1 "); + _parse_tc_handle_valid(" 1 ", 1, 0); _parse_tc_handle_valid ("1:", 1, 0); - _parse_tc_handle_inval ("1: "); + _parse_tc_handle_valid ("1: ", 1, 0); _parse_tc_handle_valid ("1:0", 1, 0); - _parse_tc_handle_inval ("1 :0"); - _parse_tc_handle_inval ("1 \t\n\f\r:0"); + _parse_tc_handle_valid ("1 :0", 1, 0); + _parse_tc_handle_valid ("1 \t\n\f\r:0", 1, 0); _parse_tc_handle_inval ("1 \t\n\f\r\v:0"); - _parse_tc_handle_inval (" 1 : 0 "); - _parse_tc_handle_valid (" \t\v\n1: 0", 1, 0); + _parse_tc_handle_valid (" 1 : 0 ", 1, 0); + _parse_tc_handle_inval (" \t\v\n1: 0"); _parse_tc_handle_valid ("1:2", 1, 2); _parse_tc_handle_valid ("01:02", 1, 2); - _parse_tc_handle_valid ("0x01:0x02", 1, 2); + _parse_tc_handle_inval ("0x01:0x02"); _parse_tc_handle_valid (" 01: 02", 1, 2); _parse_tc_handle_valid ("019: 020", 0x19, 0x20); _parse_tc_handle_valid ("FFFF: 020", 0xFFFF, 0x20); _parse_tc_handle_valid ("FfFF: ffff", 0xFFFF, 0xFFFF); _parse_tc_handle_valid ("FFFF", 0xFFFF, 0); - _parse_tc_handle_valid ("0xFFFF", 0xFFFF, 0); + _parse_tc_handle_inval ("0xFFFF"); _parse_tc_handle_inval ("10000"); _parse_tc_handle_valid ("\t\n\f\r FFFF", 0xFFFF, 0); - _parse_tc_handle_valid ("\t\n\f\r \vFFFF", 0xFFFF, 0); + _parse_tc_handle_inval ("\t\n\f\r \vFFFF"); } /*****************************************************************************/