2018-12-11 21:47:06 +01:00
|
|
|
From 259d16f0a869f9d2371036a20fb5ff19980e61b8 Mon Sep 17 00:00:00 2001
|
2017-03-15 20:38:55 +01:00
|
|
|
From: =?UTF-8?q?Andreas=20F=C3=A4rber?= <afaerber@suse.de>
|
|
|
|
Date: Thu, 24 Sep 2015 19:21:11 +0200
|
|
|
|
Subject: [PATCH] string-input-visitor: Fix uint64 parsing
|
|
|
|
MIME-Version: 1.0
|
|
|
|
Content-Type: text/plain; charset=UTF-8
|
|
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
|
|
|
|
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 this is a bug fix, it intentionally ignores checkpatch warnings to
|
|
|
|
prefer the use of qemu_strto[u]ll() over strto[u]ll().
|
|
|
|
|
|
|
|
Cc: qemu-stable@nongnu.org
|
|
|
|
Signed-off-by: Andreas Färber <afaerber@suse.de>
|
2018-12-06 22:20:59 +01:00
|
|
|
[BR: define qemu_strtoll and qemu_strtoull and use to avoid checkpatch
|
|
|
|
error. Grr}
|
|
|
|
Signed-off-by: Bruce Rogers <brogers@suse.com>
|
2017-03-15 20:38:55 +01:00
|
|
|
---
|
2018-12-06 22:20:59 +01:00
|
|
|
qapi/string-input-visitor.c | 65 +++++++++++++++++++++++++++++--------
|
|
|
|
1 file changed, 52 insertions(+), 13 deletions(-)
|
2017-03-15 20:38:55 +01:00
|
|
|
|
|
|
|
diff --git a/qapi/string-input-visitor.c b/qapi/string-input-visitor.c
|
2018-12-06 22:20:59 +01:00
|
|
|
index b3fdd0827d..ac118d03c8 100644
|
2017-03-15 20:38:55 +01:00
|
|
|
--- a/qapi/string-input-visitor.c
|
|
|
|
+++ b/qapi/string-input-visitor.c
|
2018-12-06 22:20:59 +01:00
|
|
|
@@ -21,6 +21,8 @@
|
|
|
|
#include "qemu/queue.h"
|
|
|
|
#include "qemu/range.h"
|
|
|
|
|
|
|
|
+#define qemu_strtoll strtoll
|
|
|
|
+#define qemu_strtoull strtoull
|
|
|
|
|
|
|
|
struct StringInputVisitor
|
|
|
|
{
|
|
|
|
@@ -44,7 +46,8 @@ static void free_range(void *range, void *dummy)
|
2017-03-15 20:38:55 +01:00
|
|
|
g_free(range);
|
|
|
|
}
|
|
|
|
|
|
|
|
-static int parse_str(StringInputVisitor *siv, const char *name, Error **errp)
|
|
|
|
+static int parse_str(StringInputVisitor *siv, const char *name, bool u64,
|
|
|
|
+ Error **errp)
|
|
|
|
{
|
|
|
|
char *str = (char *) siv->string;
|
|
|
|
long long start, end;
|
2018-12-06 22:20:59 +01:00
|
|
|
@@ -61,7 +64,11 @@ static int parse_str(StringInputVisitor *siv, const char *name, Error **errp)
|
2017-03-15 20:38:55 +01:00
|
|
|
|
|
|
|
do {
|
|
|
|
errno = 0;
|
|
|
|
- start = strtoll(str, &endptr, 0);
|
|
|
|
+ if (u64) {
|
2018-12-06 22:20:59 +01:00
|
|
|
+ start = qemu_strtoull(str, &endptr, 0);
|
2017-03-15 20:38:55 +01:00
|
|
|
+ } else {
|
2018-12-06 22:20:59 +01:00
|
|
|
+ start = qemu_strtoll(str, &endptr, 0);
|
2017-03-15 20:38:55 +01:00
|
|
|
+ }
|
|
|
|
if (errno == 0 && endptr > str) {
|
|
|
|
if (*endptr == '\0') {
|
|
|
|
cur = g_malloc0(sizeof(*cur));
|
2018-12-06 22:20:59 +01:00
|
|
|
@@ -72,7 +79,11 @@ static int parse_str(StringInputVisitor *siv, const char *name, Error **errp)
|
2017-03-15 20:38:55 +01:00
|
|
|
} else if (*endptr == '-') {
|
|
|
|
str = endptr + 1;
|
|
|
|
errno = 0;
|
|
|
|
- end = strtoll(str, &endptr, 0);
|
|
|
|
+ if (u64) {
|
2018-12-06 22:20:59 +01:00
|
|
|
+ end = qemu_strtoull(str, &endptr, 0);
|
2017-03-15 20:38:55 +01:00
|
|
|
+ } else {
|
2018-12-06 22:20:59 +01:00
|
|
|
+ end = qemu_strtoll(str, &endptr, 0);
|
2017-03-15 20:38:55 +01:00
|
|
|
+ }
|
|
|
|
if (errno == 0 && endptr > str && start <= end &&
|
|
|
|
(start > INT64_MAX - 65536 ||
|
|
|
|
end < start + 65536)) {
|
2018-12-06 22:20:59 +01:00
|
|
|
@@ -128,7 +139,7 @@ start_list(Visitor *v, const char *name, GenericList **list, size_t size,
|
2017-03-15 20:38:55 +01:00
|
|
|
assert(list);
|
|
|
|
siv->list = list;
|
|
|
|
|
|
|
|
- if (parse_str(siv, name, errp) < 0) {
|
|
|
|
+ if (parse_str(siv, name, false, errp) < 0) {
|
|
|
|
*list = NULL;
|
|
|
|
return;
|
|
|
|
}
|
2018-12-06 22:20:59 +01:00
|
|
|
@@ -216,7 +227,7 @@ static void parse_type_int64(Visitor *v, const char *name, int64_t *obj,
|
2017-03-29 06:22:10 +02:00
|
|
|
{
|
|
|
|
StringInputVisitor *siv = to_siv(v);
|
2017-03-15 20:38:55 +01:00
|
|
|
|
|
|
|
- if (parse_str(siv, name, errp) < 0) {
|
|
|
|
+ if (parse_str(siv, name, false, errp) < 0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-12-06 22:20:59 +01:00
|
|
|
@@ -252,15 +263,43 @@ error:
|
2017-03-15 20:38:55 +01:00
|
|
|
static void parse_type_uint64(Visitor *v, const char *name, uint64_t *obj,
|
|
|
|
Error **errp)
|
|
|
|
{
|
|
|
|
- /* FIXME: parse_type_int64 mishandles values over INT64_MAX */
|
|
|
|
- int64_t i;
|
|
|
|
- Error *err = NULL;
|
|
|
|
- parse_type_int64(v, name, &i, &err);
|
|
|
|
- if (err) {
|
|
|
|
- error_propagate(errp, err);
|
|
|
|
- } else {
|
|
|
|
- *obj = i;
|
|
|
|
+ StringInputVisitor *siv = to_siv(v);
|
|
|
|
+
|
|
|
|
+ if (!siv->string) {
|
|
|
|
+ error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
|
|
|
|
+ "integer");
|
|
|
|
+ return;
|
2018-02-08 20:55:31 +01:00
|
|
|
+ }
|
2017-03-15 20:38:55 +01:00
|
|
|
+
|
|
|
|
+ parse_str(siv, name, true, errp);
|
|
|
|
+
|
|
|
|
+ if (!siv->ranges) {
|
|
|
|
+ goto error;
|
2018-02-08 20:55:31 +01:00
|
|
|
}
|
2017-03-15 20:38:55 +01:00
|
|
|
+
|
|
|
|
+ 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 = range_lob(r);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ *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, const char *name, uint64_t *obj,
|