diff options
author | Markus Armbruster <armbru@redhat.com> | 2017-02-21 21:14:08 +0100 |
---|---|---|
committer | Markus Armbruster <armbru@redhat.com> | 2017-02-23 20:35:36 +0100 |
commit | 75cdcd1553e74b5edc58aed23e3b2da8dabb1876 (patch) | |
tree | 65345fb1cb4518f0d9ca6abef0db9486e334b985 | |
parent | f46bfdbfc8f95cf65d7818ef68a801e063c40332 (diff) |
option: Fix checking of sizes for overflow and trailing crap
parse_option_size()'s checking for overflow and trailing crap is
wrong. Has always been that way. qemu_strtosz() gets it right, so
use that.
This adds support for size suffixes 'P', 'E', and ignores case for all
suffixes, not just 'k'.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-Id: <1487708048-2131-25-git-send-email-armbru@redhat.com>
-rw-r--r-- | tests/test-qemu-opts.c | 21 | ||||
-rw-r--r-- | util/qemu-option.c | 41 |
2 files changed, 22 insertions, 40 deletions
diff --git a/tests/test-qemu-opts.c b/tests/test-qemu-opts.c index 8b92f7b0dc..c46ef31658 100644 --- a/tests/test-qemu-opts.c +++ b/tests/test-qemu-opts.c @@ -702,10 +702,9 @@ static void test_opts_parse_size(void) g_assert(!opts); opts = qemu_opts_parse(&opts_list_02, "size1=18446744073709550592", /* fffffffffffffc00 */ - false, &error_abort); - /* BUG: should reject */ - g_assert_cmpuint(opts_count(opts), ==, 1); - g_assert_cmpuint(qemu_opt_get_size(opts, "size1", 1), ==, 0); + false, &err); + error_free_or_abort(&err); + g_assert(!opts); /* Suffixes */ opts = qemu_opts_parse(&opts_list_02, "size1=8b,size2=1.5k,size3=2M", @@ -723,19 +722,17 @@ static void test_opts_parse_size(void) /* Beyond limit with suffix */ opts = qemu_opts_parse(&opts_list_02, "size1=16777216T", - false, &error_abort); - /* BUG: should reject */ - g_assert_cmpuint(opts_count(opts), ==, 1); - g_assert_cmpuint(qemu_opt_get_size(opts, "size1", 1), ==, 0); + false, &err); + error_free_or_abort(&err); + g_assert(!opts); /* Trailing crap */ opts = qemu_opts_parse(&opts_list_02, "size1=16E", false, &err); error_free_or_abort(&err); g_assert(!opts); - opts = qemu_opts_parse(&opts_list_02, "size1=16Gi", false, &error_abort); - /* BUG: should reject */ - g_assert_cmpuint(opts_count(opts), ==, 1); - g_assert_cmpuint(qemu_opt_get_size(opts, "size1", 1), ==, 16 * G_BYTE); + opts = qemu_opts_parse(&opts_list_02, "size1=16Gi", false, &err); + error_free_or_abort(&err); + g_assert(!opts); qemu_opts_reset(&opts_list_02); } diff --git a/util/qemu-option.c b/util/qemu-option.c index 273d00d485..419f2528b8 100644 --- a/util/qemu-option.c +++ b/util/qemu-option.c @@ -174,39 +174,24 @@ static const QemuOptDesc *find_desc_by_name(const QemuOptDesc *desc, void parse_option_size(const char *name, const char *value, uint64_t *ret, Error **errp) { - char *postfix; - double sizef; + uint64_t size; + int err; - sizef = strtod(value, &postfix); - if (sizef < 0 || sizef > UINT64_MAX) { - error_setg(errp, QERR_INVALID_PARAMETER_VALUE, name, - "a non-negative number below 2^64"); + err = qemu_strtosz(value, NULL, &size); + if (err == -ERANGE) { + error_setg(errp, "Value '%s' is too large for parameter '%s'", + value, name); return; } - switch (*postfix) { - case 'T': - sizef *= 1024; - /* fall through */ - case 'G': - sizef *= 1024; - /* fall through */ - case 'M': - sizef *= 1024; - /* fall through */ - case 'K': - case 'k': - sizef *= 1024; - /* fall through */ - case 'b': - case '\0': - *ret = (uint64_t) sizef; - break; - default: - error_setg(errp, QERR_INVALID_PARAMETER_VALUE, name, "a size"); - error_append_hint(errp, "You may use k, M, G or T suffixes for " - "kilobytes, megabytes, gigabytes and terabytes.\n"); + if (err) { + error_setg(errp, QERR_INVALID_PARAMETER_VALUE, name, + "a non-negative number below 2^64"); + error_append_hint(errp, "Optional suffix k, M, G, T, P or E means" + " kilo-, mega-, giga-, tera-, peta-\n" + "and exabytes, respectively.\n"); return; } + *ret = size; } bool has_help_option(const char *param) |