58fc860e6d
A couple of fixes, including one which gives confidence we can submit to Factory finally. OBS-URL: https://build.opensuse.org/request/show/612290 OBS-URL: https://build.opensuse.org/package/show/Virtualization/qemu?expand=0&rev=410
134 lines
4.1 KiB
Diff
134 lines
4.1 KiB
Diff
From 114d411a7af47fc4ccac68c5b38b99684fb0e545 Mon Sep 17 00:00:00 2001
|
|
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>
|
|
---
|
|
qapi/string-input-visitor.c | 63 +++++++++++++++++++++++++++++--------
|
|
1 file changed, 50 insertions(+), 13 deletions(-)
|
|
|
|
diff --git a/qapi/string-input-visitor.c b/qapi/string-input-visitor.c
|
|
index b3fdd0827d..d64ad081b7 100644
|
|
--- a/qapi/string-input-visitor.c
|
|
+++ b/qapi/string-input-visitor.c
|
|
@@ -44,7 +44,8 @@ static void free_range(void *range, void *dummy)
|
|
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;
|
|
@@ -61,7 +62,11 @@ static int parse_str(StringInputVisitor *siv, const char *name, 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));
|
|
@@ -72,7 +77,11 @@ static int parse_str(StringInputVisitor *siv, const char *name, Error **errp)
|
|
} else if (*endptr == '-') {
|
|
str = endptr + 1;
|
|
errno = 0;
|
|
- end = strtoll(str, &endptr, 0);
|
|
+ if (u64) {
|
|
+ end = strtoull(str, &endptr, 0);
|
|
+ } else {
|
|
+ end = strtoll(str, &endptr, 0);
|
|
+ }
|
|
if (errno == 0 && endptr > str && start <= end &&
|
|
(start > INT64_MAX - 65536 ||
|
|
end < start + 65536)) {
|
|
@@ -128,7 +137,7 @@ start_list(Visitor *v, const char *name, GenericList **list, size_t size,
|
|
assert(list);
|
|
siv->list = list;
|
|
|
|
- if (parse_str(siv, name, errp) < 0) {
|
|
+ if (parse_str(siv, name, false, errp) < 0) {
|
|
*list = NULL;
|
|
return;
|
|
}
|
|
@@ -216,7 +225,7 @@ static void parse_type_int64(Visitor *v, const char *name, int64_t *obj,
|
|
{
|
|
StringInputVisitor *siv = to_siv(v);
|
|
|
|
- if (parse_str(siv, name, errp) < 0) {
|
|
+ if (parse_str(siv, name, false, errp) < 0) {
|
|
return;
|
|
}
|
|
|
|
@@ -252,15 +261,43 @@ error:
|
|
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;
|
|
+ }
|
|
+
|
|
+ parse_str(siv, name, 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 = 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,
|