summary refs log tree commit diff
path: root/shared/nm-glib-aux/nm-enum-utils.c
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2021-02-11 18:11:46 +0100
committerMichael Biebl <biebl@debian.org>2021-02-11 18:11:46 +0100
commit80ec1decc49c72efec2a8b87c06245c92c0ab807 (patch)
treee3b229aa94e8dcf0590f2317664176e7b8f7607b /shared/nm-glib-aux/nm-enum-utils.c
parent65f86e8f56267192d42f2b629fc6b0c99fb9cd0c (diff)
New upstream version 1.29.90 upstream/1.29.90
Diffstat (limited to 'shared/nm-glib-aux/nm-enum-utils.c')
-rw-r--r--shared/nm-glib-aux/nm-enum-utils.c58
1 files changed, 38 insertions, 20 deletions
diff --git a/shared/nm-glib-aux/nm-enum-utils.c b/shared/nm-glib-aux/nm-enum-utils.c
index 5292755d..b06f2bb2 100644
--- a/shared/nm-glib-aux/nm-enum-utils.c
+++ b/shared/nm-glib-aux/nm-enum-utils.c
@@ -1,9 +1,9 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
 /*
  * Copyright (C) 2017 Red Hat, Inc.
  */
 
-#include "nm-default.h"
+#include "nm-glib-aux/nm-default-glib-i18n-lib.h"
 
 #include "nm-enum-utils.h"
 #include "nm-str-buf.h"
@@ -76,30 +76,34 @@ _ASSERT_enum_values_info(GType type, const NMUtilsEnumValueInfo *value_infos)
 }
 
 static gboolean
-_is_hex_string(const char *str)
+_is_hex_string(const char *str, gboolean allow_sign)
 {
+    if (allow_sign && str[0] == '-')
+        str++;
     return str[0] == '0' && str[1] == 'x' && str[2]
            && NM_STRCHAR_ALL(&str[2], ch, g_ascii_isxdigit(ch));
 }
 
 static gboolean
-_is_dec_string(const char *str)
+_is_dec_string(const char *str, gboolean allow_sign)
 {
+    if (allow_sign && str[0] == '-')
+        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)) && !_is_dec_string(str)
-           && !_is_hex_string(str);
+    return str[0] && !NM_STRCHAR_ANY(str, ch, g_ascii_isspace(ch)) && !_is_dec_string(str, TRUE)
+           && !_is_hex_string(str, TRUE);
 }
 
 static gboolean
 _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);
+    return str[0] && !NM_STRCHAR_ANY(str, ch, IS_FLAGS_SEPARATOR(ch)) && !_is_dec_string(str, FALSE)
+           && !_is_hex_string(str, FALSE);
 }
 
 char *
@@ -212,8 +216,7 @@ _nm_utils_enum_from_str_full(GType                       type,
 
     _ASSERT_enum_values_info(type, value_infos);
 
-    str_clone = strdup(str);
-    s         = nm_str_skip_leading_spaces(str_clone);
+    s = nm_strdup_maybe_a(300, nm_str_skip_leading_spaces(str), &str_clone);
     g_strchomp(s);
 
     klass = g_type_class_ref(type);
@@ -221,16 +224,31 @@ _nm_utils_enum_from_str_full(GType                       type,
     if (G_IS_ENUM_CLASS(klass)) {
         GEnumValue *enum_value;
 
+        G_STATIC_ASSERT(G_MAXINT < G_MAXINT64);
+        G_STATIC_ASSERT(G_MININT > G_MININT64);
+
         if (s[0]) {
-            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;
+            if (_is_hex_string(s, TRUE)) {
+                if (s[0] == '-') {
+                    v64 = _nm_utils_ascii_str_to_int64(&s[3],
+                                                       16,
+                                                       -((gint64) G_MAXINT),
+                                                       -((gint64) G_MININT),
+                                                       G_MAXINT64);
+                    if (v64 != G_MAXINT64) {
+                        value = (int) (-v64);
+                        ret   = TRUE;
+                    }
+                } else {
+                    v64 = _nm_utils_ascii_str_to_int64(&s[2], 16, G_MININT, G_MAXINT, G_MAXINT64);
+                    if (v64 != G_MAXINT64) {
+                        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) {
+            } else if (_is_dec_string(s, TRUE)) {
+                v64 = _nm_utils_ascii_str_to_int64(s, 10, G_MININT, G_MAXINT, G_MAXINT64);
+                if (v64 != G_MAXINT64) {
                     value = (int) v64;
                     ret   = TRUE;
                 }
@@ -259,14 +277,14 @@ _nm_utils_enum_from_str_full(GType                       type,
             }
 
             if (s[0]) {
-                if (_is_hex_string(s)) {
+                if (_is_hex_string(s, FALSE)) {
                     v64 = _nm_utils_ascii_str_to_int64(&s[2], 16, 0, G_MAXUINT, -1);
                     if (v64 == -1) {
                         ret = FALSE;
                         break;
                     }
                     uvalue |= (unsigned) v64;
-                } else if (_is_dec_string(s)) {
+                } else if (_is_dec_string(s, FALSE)) {
                     v64 = _nm_utils_ascii_str_to_int64(s, 10, 0, G_MAXUINT, -1);
                     if (v64 == -1) {
                         ret = FALSE;