qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 1/7] string-input-visitor: Fix uint64 parsing


From: Andreas Färber
Subject: [Qemu-devel] [PATCH 1/7] string-input-visitor: Fix uint64 parsing
Date: Fri, 25 Sep 2015 14:39:42 +0200

All integers would get parsed by strtoll(), not handling the case of
UINT64 properties with the most significient bit set.

Implement a .type_uint64 visitor callback, reusing the existing
parse_str() code through a new argument, using strtoull().

As a bug fix, ignore warnings about preference of qemu_strto[u]ll().

Cc: address@hidden
Signed-off-by: Andreas Färber <address@hidden>
---
 qapi/string-input-visitor.c | 57 +++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 52 insertions(+), 5 deletions(-)

diff --git a/qapi/string-input-visitor.c b/qapi/string-input-visitor.c
index bbd6a54..cf81f85 100644
--- a/qapi/string-input-visitor.c
+++ b/qapi/string-input-visitor.c
@@ -37,7 +37,7 @@ static void free_range(void *range, void *dummy)
     g_free(range);
 }
 
-static void parse_str(StringInputVisitor *siv, Error **errp)
+static void parse_str(StringInputVisitor *siv, bool u64, Error **errp)
 {
     char *str = (char *) siv->string;
     long long start, end;
@@ -50,7 +50,11 @@ static void parse_str(StringInputVisitor *siv, Error **errp)
 
     do {
         errno = 0;
-        start = strtoll(str, &endptr, 0);
+        if (u64) {
+            start = strtoull(str, &endptr, 0);
+        } else {
+            start = strtoll(str, &endptr, 0);
+        }
         if (errno == 0 && endptr > str) {
             if (*endptr == '\0') {
                 cur = g_malloc0(sizeof(*cur));
@@ -60,7 +64,7 @@ static void parse_str(StringInputVisitor *siv, Error **errp)
                                                           range_compare);
                 cur = NULL;
                 str = NULL;
-            } else if (*endptr == '-') {
+            } else if (*endptr == '-' && !u64) {
                 str = endptr + 1;
                 errno = 0;
                 end = strtoll(str, &endptr, 0);
@@ -122,7 +126,7 @@ start_list(Visitor *v, const char *name, Error **errp)
 {
     StringInputVisitor *siv = DO_UPCAST(StringInputVisitor, visitor, v);
 
-    parse_str(siv, errp);
+    parse_str(siv, false, errp);
 
     siv->cur_range = g_list_first(siv->ranges);
     if (siv->cur_range) {
@@ -190,7 +194,7 @@ static void parse_type_int(Visitor *v, int64_t *obj, const 
char *name,
         return;
     }
 
-    parse_str(siv, errp);
+    parse_str(siv, false, errp);
 
     if (!siv->ranges) {
         goto error;
@@ -221,6 +225,48 @@ error:
                "an int64 value or range");
 }
 
+static void parse_type_uint64(Visitor *v, uint64_t *obj, const char *name,
+                              Error **errp)
+{
+    StringInputVisitor *siv = DO_UPCAST(StringInputVisitor, visitor, v);
+
+    if (!siv->string) {
+        error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
+                   "integer");
+        return;
+    }
+
+    parse_str(siv, true, errp);
+
+    if (!siv->ranges) {
+        goto error;
+    }
+
+    if (!siv->cur_range) {
+        Range *r;
+
+        siv->cur_range = g_list_first(siv->ranges);
+        if (!siv->cur_range) {
+            goto error;
+        }
+
+        r = siv->cur_range->data;
+        if (!r) {
+            goto error;
+        }
+
+        siv->cur = r->begin;
+    }
+
+    *obj = siv->cur;
+    siv->cur++;
+    return;
+
+error:
+    error_setg(errp, QERR_INVALID_PARAMETER_VALUE, name,
+               "a uint64 value or range");
+}
+
 static void parse_type_size(Visitor *v, uint64_t *obj, const char *name,
                             Error **errp)
 {
@@ -332,6 +378,7 @@ StringInputVisitor *string_input_visitor_new(const char 
*str)
 
     v->visitor.type_enum = input_type_enum;
     v->visitor.type_int = parse_type_int;
+    v->visitor.type_uint64 = parse_type_uint64;
     v->visitor.type_size = parse_type_size;
     v->visitor.type_bool = parse_type_bool;
     v->visitor.type_str = parse_type_str;
-- 
2.1.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]