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) { + err = qemu_strtosz(value, NULL, &size); + if (err == -ERANGE) { + error_setg(errp, "Value '%s' is too large for parameter '%s'", + value, name); + return; + } + 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; } - 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"); - return; - } + *ret = size; } bool has_help_option(const char *param)