* [Qemu-devel] [PULL 00/24] option cutils: Fix and clean up number conversions
@ 2017-02-23 19:53 Markus Armbruster
2017-02-23 19:53 ` [Qemu-devel] [PULL 01/24] test-qemu-opts: Cover qemu_opts_parse() Markus Armbruster
` (25 more replies)
0 siblings, 26 replies; 27+ messages in thread
From: Markus Armbruster @ 2017-02-23 19:53 UTC (permalink / raw)
To: qemu-devel
QemuOpts has its own code to convert strings to numbers, and being
QemuOpts, it gets it wrong. util/cutils is less wrong. Fix it up
some, and reuse it for QemuOpts.
The following changes since commit 10f25e4844cb9b3f02fb032f88051dd5b65b4206:
Merge remote-tracking branch 'remotes/yongbok/tags/mips-20170222' into staging (2017-02-23 09:59:40 +0000)
are available in the git repository at:
git://repo.or.cz/qemu/armbru.git tags/pull-util-2017-02-23
for you to fetch changes up to 75cdcd1553e74b5edc58aed23e3b2da8dabb1876:
option: Fix checking of sizes for overflow and trailing crap (2017-02-23 20:35:36 +0100)
----------------------------------------------------------------
option cutils: Fix and clean up number conversions
----------------------------------------------------------------
Markus Armbruster (24):
test-qemu-opts: Cover qemu_opts_parse()
option: Assert value string isn't null
test-cutils: Add missing qemu_strtol()... endptr checks
test-cutils: Clean up qemu_strtoul() result checks
util/cutils: Rewrite documentation of qemu_strtol() & friends
util/cutils: Rename qemu_strtoll(), qemu_strtoull()
util/cutils: Clean up variable names around qemu_strtol()
util/cutils: Clean up control flow around qemu_strtol() a bit
option: Fix to reject invalid and overflowing numbers
test-cutils: Add missing qemu_strtosz()... endptr checks
test-cutils: Cover qemu_strtosz() invalid input
test-cutils: Cover qemu_strtosz() with trailing crap
test-cutils: Cover qemu_strtosz() around range limits
util/cutils: New qemu_strtosz_metric()
util/cutils: Rename qemu_strtosz() to qemu_strtosz_MiB()
util/cutils: New qemu_strtosz()
util/cutils: Drop QEMU_STRTOSZ_DEFSUFFIX_* macros
test-cutils: Use qemu_strtosz() more often
test-cutils: Drop suffix from test_qemu_strtosz_simple()
qemu-img: Wrap cvtnum() around qemu_strtosz()
util/cutils: Let qemu_strtosz*() optionally reject trailing crap
util/cutils: Return qemu_strtosz*() error and value separately
util/cutils: Change qemu_strtosz*() from int64_t to uint64_t
option: Fix checking of sizes for overflow and trailing crap
hmp.c | 11 +-
hw/misc/ivshmem.c | 9 +-
include/qemu/cutils.h | 29 +--
monitor.c | 7 +-
qapi/opts-visitor.c | 11 +-
qemu-img.c | 62 ++---
qemu-io-cmds.c | 16 +-
qobject/qdict.c | 2 +-
qtest.c | 34 +--
target/i386/cpu.c | 9 +-
tests/test-cutils.c | 642 ++++++++++++++++++++++++++++++++-----------------
tests/test-qemu-opts.c | 324 ++++++++++++++++++++++++-
util/cutils.c | 239 +++++++++---------
util/log.c | 4 +-
util/qemu-option.c | 87 +++----
15 files changed, 994 insertions(+), 492 deletions(-)
--
2.7.4
^ permalink raw reply [flat|nested] 27+ messages in thread
* [Qemu-devel] [PULL 01/24] test-qemu-opts: Cover qemu_opts_parse()
2017-02-23 19:53 [Qemu-devel] [PULL 00/24] option cutils: Fix and clean up number conversions Markus Armbruster
@ 2017-02-23 19:53 ` Markus Armbruster
2017-02-23 19:53 ` [Qemu-devel] [PULL 02/24] option: Assert value string isn't null Markus Armbruster
` (24 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Markus Armbruster @ 2017-02-23 19:53 UTC (permalink / raw)
To: qemu-devel
The new tests demonstrate a few bugs, all clearly marked.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-Id: <1487708048-2131-2-git-send-email-armbru@redhat.com>
[A few additional test cases squashed in, see
Message-ID: <871supjijq.fsf@dusky.pond.sub.org>]
---
tests/test-qemu-opts.c | 330 ++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 328 insertions(+), 2 deletions(-)
diff --git a/tests/test-qemu-opts.c b/tests/test-qemu-opts.c
index a505a3e..310485b 100644
--- a/tests/test-qemu-opts.c
+++ b/tests/test-qemu-opts.c
@@ -8,6 +8,7 @@
*/
#include "qemu/osdep.h"
+#include "qemu/cutils.h"
#include "qapi/error.h"
#include "qapi/qmp/qstring.h"
#include "qemu/config-file.h"
@@ -29,6 +30,9 @@ static QemuOptsList opts_list_01 = {
},{
.name = "number1",
.type = QEMU_OPT_NUMBER,
+ },{
+ .name = "number2",
+ .type = QEMU_OPT_NUMBER,
},
{ /* end of list */ }
},
@@ -42,14 +46,23 @@ static QemuOptsList opts_list_02 = {
.name = "str1",
.type = QEMU_OPT_STRING,
},{
+ .name = "str2",
+ .type = QEMU_OPT_STRING,
+ },{
.name = "bool1",
.type = QEMU_OPT_BOOL,
},{
- .name = "str2",
- .type = QEMU_OPT_STRING,
+ .name = "bool2",
+ .type = QEMU_OPT_BOOL,
},{
.name = "size1",
.type = QEMU_OPT_SIZE,
+ },{
+ .name = "size2",
+ .type = QEMU_OPT_SIZE,
+ },{
+ .name = "size3",
+ .type = QEMU_OPT_SIZE,
},
{ /* end of list */ }
},
@@ -57,6 +70,7 @@ static QemuOptsList opts_list_02 = {
static QemuOptsList opts_list_03 = {
.name = "opts_list_03",
+ .implied_opt_name = "implied",
.head = QTAILQ_HEAD_INITIALIZER(opts_list_03.head),
.desc = {
/* no elements => accept any params */
@@ -421,6 +435,314 @@ static void test_qemu_opts_set(void)
g_assert(opts == NULL);
}
+static int opts_count_iter(void *opaque, const char *name, const char *value,
+ Error **errp)
+{
+ (*(size_t *)opaque)++;
+ return 0;
+}
+
+static size_t opts_count(QemuOpts *opts)
+{
+ size_t n = 0;
+
+ qemu_opt_foreach(opts, opts_count_iter, &n, NULL);
+ return n;
+}
+
+static void test_opts_parse(void)
+{
+ Error *err = NULL;
+ QemuOpts *opts;
+ char long_key[129];
+ char *params;
+
+ /* Nothing */
+ opts = qemu_opts_parse(&opts_list_03, "", false, &error_abort);
+ g_assert_cmpuint(opts_count(opts), ==, 0);
+
+ /* Empty key */
+ opts = qemu_opts_parse(&opts_list_03, "=val", false, &error_abort);
+ g_assert_cmpuint(opts_count(opts), ==, 1);
+ g_assert_cmpstr(qemu_opt_get(opts, ""), ==, "val");
+
+ /* Long key */
+ memset(long_key, 'a', 127);
+ long_key[127] = 'z';
+ long_key[128] = 0;
+ params = g_strdup_printf("%s=v", long_key);
+ opts = qemu_opts_parse(&opts_list_03, params + 1, NULL, &error_abort);
+ g_assert_cmpuint(opts_count(opts), ==, 1);
+ g_assert_cmpstr(qemu_opt_get(opts, long_key + 1), ==, "v");
+
+ /* Overlong key gets truncated */
+ opts = qemu_opts_parse(&opts_list_03, params, NULL, &error_abort);
+ g_assert(opts_count(opts) == 1);
+ long_key[127] = 0;
+ g_assert_cmpstr(qemu_opt_get(opts, long_key), ==, "v");
+ g_free(params);
+
+ /* Multiple keys, last one wins */
+ opts = qemu_opts_parse(&opts_list_03, "a=1,b=2,,x,a=3",
+ false, &error_abort);
+ g_assert_cmpuint(opts_count(opts), ==, 3);
+ g_assert_cmpstr(qemu_opt_get(opts, "a"), ==, "3");
+ g_assert_cmpstr(qemu_opt_get(opts, "b"), ==, "2,x");
+
+ /* Except when it doesn't */
+ opts = qemu_opts_parse(&opts_list_03, "id=foo,id=bar",
+ false, &error_abort);
+ g_assert_cmpuint(opts_count(opts), ==, 0);
+ g_assert_cmpstr(qemu_opts_id(opts), ==, "foo");
+
+ /* TODO Cover low-level access to repeated keys */
+
+ /* Trailing comma is ignored */
+ opts = qemu_opts_parse(&opts_list_03, "x=y,", false, &error_abort);
+ g_assert_cmpuint(opts_count(opts), ==, 1);
+ g_assert_cmpstr(qemu_opt_get(opts, "x"), ==, "y");
+
+ /* Except when it isn't */
+ opts = qemu_opts_parse(&opts_list_03, ",", false, &error_abort);
+ g_assert_cmpuint(opts_count(opts), ==, 1);
+ g_assert_cmpstr(qemu_opt_get(opts, ""), ==, "on");
+
+ /* Duplicate ID */
+ opts = qemu_opts_parse(&opts_list_03, "x=y,id=foo", false, &err);
+ error_free_or_abort(&err);
+ g_assert(!opts);
+ /* TODO Cover .merge_lists = true */
+
+ /* Buggy ID recognition */
+ opts = qemu_opts_parse(&opts_list_03, "x=,,id=bar", false, &error_abort);
+ g_assert_cmpuint(opts_count(opts), ==, 1);
+ g_assert_cmpstr(qemu_opts_id(opts), ==, "bar"); /* BUG */
+ g_assert_cmpstr(qemu_opt_get(opts, "x"), ==, ",id=bar");
+
+ /* Anti-social ID */
+ opts = qemu_opts_parse(&opts_list_01, "id=666", false, &err);
+ error_free_or_abort(&err);
+ g_assert(!opts);
+
+ /* Implied value */
+ opts = qemu_opts_parse(&opts_list_03, "an,noaus,noaus=",
+ false, &error_abort);
+ g_assert_cmpuint(opts_count(opts), ==, 3);
+ g_assert_cmpstr(qemu_opt_get(opts, "an"), ==, "on");
+ g_assert_cmpstr(qemu_opt_get(opts, "aus"), ==, "off");
+ g_assert_cmpstr(qemu_opt_get(opts, "noaus"), ==, "");
+
+ /* Implied key */
+ opts = qemu_opts_parse(&opts_list_03, "an,noaus,noaus=", true,
+ &error_abort);
+ g_assert_cmpuint(opts_count(opts), ==, 3);
+ g_assert_cmpstr(qemu_opt_get(opts, "implied"), ==, "an");
+ g_assert_cmpstr(qemu_opt_get(opts, "aus"), ==, "off");
+ g_assert_cmpstr(qemu_opt_get(opts, "noaus"), ==, "");
+
+ /* Implied key with empty value */
+ opts = qemu_opts_parse(&opts_list_03, ",", true, &error_abort);
+ g_assert_cmpuint(opts_count(opts), ==, 1);
+ g_assert_cmpstr(qemu_opt_get(opts, "implied"), ==, "");
+
+ /* Implied key with comma value */
+ opts = qemu_opts_parse(&opts_list_03, ",,,a=1", true, &error_abort);
+ g_assert_cmpuint(opts_count(opts), ==, 2);
+ g_assert_cmpstr(qemu_opt_get(opts, "implied"), ==, ",");
+ g_assert_cmpstr(qemu_opt_get(opts, "a"), ==, "1");
+
+ /* Empty key is not an implied key */
+ opts = qemu_opts_parse(&opts_list_03, "=val", true, &error_abort);
+ g_assert_cmpuint(opts_count(opts), ==, 1);
+ g_assert_cmpstr(qemu_opt_get(opts, ""), ==, "val");
+
+ /* Unknown key */
+ opts = qemu_opts_parse(&opts_list_01, "nonexistent=", false, &err);
+ error_free_or_abort(&err);
+ g_assert(!opts);
+
+ qemu_opts_reset(&opts_list_01);
+ qemu_opts_reset(&opts_list_03);
+}
+
+static void test_opts_parse_bool(void)
+{
+ Error *err = NULL;
+ QemuOpts *opts;
+
+ opts = qemu_opts_parse(&opts_list_02, "bool1=on,bool2=off",
+ false, &error_abort);
+ g_assert_cmpuint(opts_count(opts), ==, 2);
+ g_assert(qemu_opt_get_bool(opts, "bool1", false));
+ g_assert(!qemu_opt_get_bool(opts, "bool2", true));
+
+ opts = qemu_opts_parse(&opts_list_02, "bool1=offer", false, &err);
+ error_free_or_abort(&err);
+ g_assert(!opts);
+
+ qemu_opts_reset(&opts_list_02);
+}
+
+static void test_opts_parse_number(void)
+{
+ Error *err = NULL;
+ QemuOpts *opts;
+
+ /* Lower limit zero */
+ opts = qemu_opts_parse(&opts_list_01, "number1=0", false, &error_abort);
+ g_assert_cmpuint(opts_count(opts), ==, 1);
+ g_assert_cmpuint(qemu_opt_get_number(opts, "number1", 1), ==, 0);
+
+ /* Upper limit 2^64-1 */
+ opts = qemu_opts_parse(&opts_list_01,
+ "number1=18446744073709551615,number2=-1",
+ false, &error_abort);
+ g_assert_cmpuint(opts_count(opts), ==, 2);
+ g_assert_cmphex(qemu_opt_get_number(opts, "number1", 1), ==, UINT64_MAX);
+ g_assert_cmphex(qemu_opt_get_number(opts, "number2", 0), ==, UINT64_MAX);
+
+ /* Above upper limit */
+ opts = qemu_opts_parse(&opts_list_01, "number1=18446744073709551616",
+ false, &error_abort);
+ /* BUG: should reject */
+ g_assert_cmpuint(opts_count(opts), ==, 1);
+ g_assert_cmpuint(qemu_opt_get_number(opts, "number1", 1), ==, UINT64_MAX);
+
+ /* Below lower limit */
+ opts = qemu_opts_parse(&opts_list_01, "number1=-18446744073709551616",
+ false, &error_abort);
+ /* BUG: should reject */
+ g_assert_cmpuint(opts_count(opts), ==, 1);
+ g_assert_cmpuint(qemu_opt_get_number(opts, "number1", 1), ==, UINT64_MAX);
+
+ /* Hex and octal */
+ opts = qemu_opts_parse(&opts_list_01, "number1=0x2a,number2=052",
+ false, &error_abort);
+ g_assert_cmpuint(opts_count(opts), ==, 2);
+ g_assert_cmpuint(qemu_opt_get_number(opts, "number1", 1), ==, 42);
+ g_assert_cmpuint(qemu_opt_get_number(opts, "number2", 0), ==, 42);
+
+ /* Invalid */
+ opts = qemu_opts_parse(&opts_list_01, "number1=", false, &err);
+ /* BUG: should reject */
+ g_assert_cmpuint(opts_count(opts), ==, 1);
+ g_assert_cmpuint(qemu_opt_get_number(opts, "number1", 1), ==, 0);
+ opts = qemu_opts_parse(&opts_list_01, "number1=eins", false, &err);
+ error_free_or_abort(&err);
+ g_assert(!opts);
+
+ /* Leading whitespace */
+ opts = qemu_opts_parse(&opts_list_01, "number1= \t42",
+ false, &error_abort);
+ g_assert_cmpuint(opts_count(opts), ==, 1);
+ g_assert_cmpuint(qemu_opt_get_number(opts, "number1", 1), ==, 42);
+
+ /* Trailing crap */
+ opts = qemu_opts_parse(&opts_list_01, "number1=3.14", false, &err);
+ error_free_or_abort(&err);
+ g_assert(!opts);
+ opts = qemu_opts_parse(&opts_list_01, "number1=08", false, &err);
+ error_free_or_abort(&err);
+ g_assert(!opts);
+ opts = qemu_opts_parse(&opts_list_01, "number1=0 ", false, &err);
+ error_free_or_abort(&err);
+ g_assert(!opts);
+
+ qemu_opts_reset(&opts_list_01);
+}
+
+static void test_opts_parse_size(void)
+{
+ Error *err = NULL;
+ QemuOpts *opts;
+
+ /* Lower limit zero */
+ opts = qemu_opts_parse(&opts_list_02, "size1=0", false, &error_abort);
+ g_assert_cmpuint(opts_count(opts), ==, 1);
+ g_assert_cmpuint(qemu_opt_get_size(opts, "size1", 1), ==, 0);
+
+ /* Note: precision is 53 bits since we're parsing with strtod() */
+
+ /* Around limit of precision: 2^53-1, 2^53, 2^54 */
+ opts = qemu_opts_parse(&opts_list_02,
+ "size1=9007199254740991,"
+ "size2=9007199254740992,"
+ "size3=9007199254740993",
+ false, &error_abort);
+ g_assert_cmpuint(opts_count(opts), ==, 3);
+ g_assert_cmphex(qemu_opt_get_size(opts, "size1", 1),
+ ==, 0x1fffffffffffff);
+ g_assert_cmphex(qemu_opt_get_size(opts, "size2", 1),
+ ==, 0x20000000000000);
+ g_assert_cmphex(qemu_opt_get_size(opts, "size3", 1),
+ ==, 0x20000000000000);
+
+ /* Close to signed upper limit 0x7ffffffffffffc00 (53 msbs set) */
+ opts = qemu_opts_parse(&opts_list_02,
+ "size1=9223372036854774784," /* 7ffffffffffffc00 */
+ "size2=9223372036854775295", /* 7ffffffffffffdff */
+ false, &error_abort);
+ g_assert_cmpuint(opts_count(opts), ==, 2);
+ g_assert_cmphex(qemu_opt_get_size(opts, "size1", 1),
+ ==, 0x7ffffffffffffc00);
+ g_assert_cmphex(qemu_opt_get_size(opts, "size2", 1),
+ ==, 0x7ffffffffffffc00);
+
+ /* Close to actual upper limit 0xfffffffffffff800 (53 msbs set) */
+ opts = qemu_opts_parse(&opts_list_02,
+ "size1=18446744073709549568," /* fffffffffffff800 */
+ "size2=18446744073709550591", /* fffffffffffffbff */
+ false, &error_abort);
+ g_assert_cmpuint(opts_count(opts), ==, 2);
+ g_assert_cmphex(qemu_opt_get_size(opts, "size1", 1),
+ ==, 0xfffffffffffff800);
+ g_assert_cmphex(qemu_opt_get_size(opts, "size2", 1),
+ ==, 0xfffffffffffff800);
+
+ /* Beyond limits */
+ opts = qemu_opts_parse(&opts_list_02, "size1=-1", false, &err);
+ error_free_or_abort(&err);
+ 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);
+
+ /* Suffixes */
+ opts = qemu_opts_parse(&opts_list_02, "size1=8b,size2=1.5k,size3=2M",
+ false, &error_abort);
+ g_assert_cmpuint(opts_count(opts), ==, 3);
+ g_assert_cmphex(qemu_opt_get_size(opts, "size1", 0), ==, 8);
+ g_assert_cmphex(qemu_opt_get_size(opts, "size2", 0), ==, 1536);
+ g_assert_cmphex(qemu_opt_get_size(opts, "size3", 0), ==, 2 * M_BYTE);
+ opts = qemu_opts_parse(&opts_list_02, "size1=0.1G,size2=16777215T",
+ false, &error_abort);
+ g_assert_cmpuint(opts_count(opts), ==, 2);
+ g_assert_cmphex(qemu_opt_get_size(opts, "size1", 0), ==, G_BYTE / 10);
+ g_assert_cmphex(qemu_opt_get_size(opts, "size2", 0),
+ ==, 16777215 * T_BYTE);
+
+ /* 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);
+
+ /* 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);
+
+ qemu_opts_reset(&opts_list_02);
+}
+
int main(int argc, char *argv[])
{
register_opts();
@@ -435,6 +757,10 @@ int main(int argc, char *argv[])
g_test_add_func("/qemu-opts/opt_unset", test_qemu_opt_unset);
g_test_add_func("/qemu-opts/opts_reset", test_qemu_opts_reset);
g_test_add_func("/qemu-opts/opts_set", test_qemu_opts_set);
+ g_test_add_func("/qemu-opts/opts_parse/general", test_opts_parse);
+ g_test_add_func("/qemu-opts/opts_parse/bool", test_opts_parse_bool);
+ g_test_add_func("/qemu-opts/opts_parse/number", test_opts_parse_number);
+ g_test_add_func("/qemu-opts/opts_parse/size", test_opts_parse_size);
g_test_run();
return 0;
}
--
2.7.4
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [Qemu-devel] [PULL 02/24] option: Assert value string isn't null
2017-02-23 19:53 [Qemu-devel] [PULL 00/24] option cutils: Fix and clean up number conversions Markus Armbruster
2017-02-23 19:53 ` [Qemu-devel] [PULL 01/24] test-qemu-opts: Cover qemu_opts_parse() Markus Armbruster
@ 2017-02-23 19:53 ` Markus Armbruster
2017-02-23 19:53 ` [Qemu-devel] [PULL 03/24] test-cutils: Add missing qemu_strtol()... endptr checks Markus Armbruster
` (23 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Markus Armbruster @ 2017-02-23 19:53 UTC (permalink / raw)
To: qemu-devel
Plenty of code relies on QemuOpt member @str not being null, including
qemu_opts_print(), qemu_opts_to_qdict(), and callbacks passed to
qemu_opt_foreach().
Begs the question whether it can be null. Only opt_set() creates
QemuOpt. It sets member @str to its argument @value. Passing null
for @value would plant a time bomb. Callers:
* opts_do_parse() can't pass null.
* qemu_opt_set() passes its argument @value. Callers:
- qemu_opts_from_qdict_1() can't pass null
- qemu_opts_set() passes its argument @value, but none of its
callers pass null.
- Many more outside qemu-option.c, but they shouldn't pass null,
either.
Assert member @str isn't null, so that misuse is caught right away.
Simplify parse_option_bool(), parse_option_number() and
parse_option_size() accordingly. Best viewed with whitespace changes
ignored.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-Id: <1487708048-2131-3-git-send-email-armbru@redhat.com>
---
util/qemu-option.c | 89 ++++++++++++++++++++++++------------------------------
1 file changed, 39 insertions(+), 50 deletions(-)
diff --git a/util/qemu-option.c b/util/qemu-option.c
index d611946..9708668 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -128,17 +128,13 @@ int get_param_value(char *buf, int buf_size,
static void parse_option_bool(const char *name, const char *value, bool *ret,
Error **errp)
{
- if (value != NULL) {
- if (!strcmp(value, "on")) {
- *ret = 1;
- } else if (!strcmp(value, "off")) {
- *ret = 0;
- } else {
- error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
- name, "'on' or 'off'");
- }
- } else {
+ if (!strcmp(value, "on")) {
*ret = 1;
+ } else if (!strcmp(value, "off")) {
+ *ret = 0;
+ } else {
+ error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
+ name, "'on' or 'off'");
}
}
@@ -148,16 +144,12 @@ static void parse_option_number(const char *name, const char *value,
char *postfix;
uint64_t number;
- if (value != NULL) {
- number = strtoull(value, &postfix, 0);
- if (*postfix != '\0') {
- error_setg(errp, QERR_INVALID_PARAMETER_VALUE, name, "a number");
- return;
- }
- *ret = number;
- } else {
+ number = strtoull(value, &postfix, 0);
+ if (*postfix != '\0') {
error_setg(errp, QERR_INVALID_PARAMETER_VALUE, name, "a number");
+ return;
}
+ *ret = number;
}
static const QemuOptDesc *find_desc_by_name(const QemuOptDesc *desc,
@@ -180,39 +172,35 @@ void parse_option_size(const char *name, const char *value,
char *postfix;
double sizef;
- if (value != NULL) {
- 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");
- 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;
- }
- } else {
+ 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");
+ 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;
}
}
@@ -566,6 +554,7 @@ static void opt_set(QemuOpts *opts, const char *name, const char *value,
}
opt->desc = desc;
opt->str = g_strdup(value);
+ assert(opt->str);
qemu_opt_parse(opt, &local_err);
if (local_err) {
error_propagate(errp, local_err);
--
2.7.4
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [Qemu-devel] [PULL 03/24] test-cutils: Add missing qemu_strtol()... endptr checks
2017-02-23 19:53 [Qemu-devel] [PULL 00/24] option cutils: Fix and clean up number conversions Markus Armbruster
2017-02-23 19:53 ` [Qemu-devel] [PULL 01/24] test-qemu-opts: Cover qemu_opts_parse() Markus Armbruster
2017-02-23 19:53 ` [Qemu-devel] [PULL 02/24] option: Assert value string isn't null Markus Armbruster
@ 2017-02-23 19:53 ` Markus Armbruster
2017-02-23 19:53 ` [Qemu-devel] [PULL 04/24] test-cutils: Clean up qemu_strtoul() result checks Markus Armbruster
` (22 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Markus Armbruster @ 2017-02-23 19:53 UTC (permalink / raw)
To: qemu-devel
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-Id: <1487708048-2131-4-git-send-email-armbru@redhat.com>
---
tests/test-cutils.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/tests/test-cutils.c b/tests/test-cutils.c
index 20b0f59..71681dc 100644
--- a/tests/test-cutils.c
+++ b/tests/test-cutils.c
@@ -262,6 +262,7 @@ static void test_qemu_strtol_empty(void)
err = qemu_strtol(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, -EINVAL);
+ g_assert(endptr == str);
}
static void test_qemu_strtol_whitespace(void)
@@ -275,6 +276,7 @@ static void test_qemu_strtol_whitespace(void)
err = qemu_strtol(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, -EINVAL);
+ g_assert(endptr == str);
}
static void test_qemu_strtol_invalid(void)
@@ -288,6 +290,7 @@ static void test_qemu_strtol_invalid(void)
err = qemu_strtol(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, -EINVAL);
+ g_assert(endptr == str);
}
static void test_qemu_strtol_trailing(void)
@@ -548,6 +551,7 @@ static void test_qemu_strtoul_empty(void)
err = qemu_strtoul(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, -EINVAL);
+ g_assert(endptr == str);
}
static void test_qemu_strtoul_whitespace(void)
@@ -561,6 +565,7 @@ static void test_qemu_strtoul_whitespace(void)
err = qemu_strtoul(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, -EINVAL);
+ g_assert(endptr == str);
}
static void test_qemu_strtoul_invalid(void)
@@ -574,6 +579,7 @@ static void test_qemu_strtoul_invalid(void)
err = qemu_strtoul(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, -EINVAL);
+ g_assert(endptr == str);
}
static void test_qemu_strtoul_trailing(void)
@@ -829,6 +835,7 @@ static void test_qemu_strtoll_empty(void)
err = qemu_strtoll(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, -EINVAL);
+ g_assert(endptr == str);
}
static void test_qemu_strtoll_whitespace(void)
@@ -842,6 +849,7 @@ static void test_qemu_strtoll_whitespace(void)
err = qemu_strtoll(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, -EINVAL);
+ g_assert(endptr == str);
}
static void test_qemu_strtoll_invalid(void)
@@ -855,6 +863,7 @@ static void test_qemu_strtoll_invalid(void)
err = qemu_strtoll(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, -EINVAL);
+ g_assert(endptr == str);
}
static void test_qemu_strtoll_trailing(void)
@@ -1113,6 +1122,7 @@ static void test_qemu_strtoull_empty(void)
err = qemu_strtoull(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, -EINVAL);
+ g_assert(endptr == str);
}
static void test_qemu_strtoull_whitespace(void)
@@ -1126,6 +1136,7 @@ static void test_qemu_strtoull_whitespace(void)
err = qemu_strtoull(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, -EINVAL);
+ g_assert(endptr == str);
}
static void test_qemu_strtoull_invalid(void)
@@ -1139,6 +1150,7 @@ static void test_qemu_strtoull_invalid(void)
err = qemu_strtoull(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, -EINVAL);
+ g_assert(endptr == str);
}
static void test_qemu_strtoull_trailing(void)
--
2.7.4
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [Qemu-devel] [PULL 04/24] test-cutils: Clean up qemu_strtoul() result checks
2017-02-23 19:53 [Qemu-devel] [PULL 00/24] option cutils: Fix and clean up number conversions Markus Armbruster
` (2 preceding siblings ...)
2017-02-23 19:53 ` [Qemu-devel] [PULL 03/24] test-cutils: Add missing qemu_strtol()... endptr checks Markus Armbruster
@ 2017-02-23 19:53 ` Markus Armbruster
2017-02-23 19:53 ` [Qemu-devel] [PULL 05/24] util/cutils: Rewrite documentation of qemu_strtol() & friends Markus Armbruster
` (21 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Markus Armbruster @ 2017-02-23 19:53 UTC (permalink / raw)
To: qemu-devel
Use unsigned comparisons to check the result of qemu_strtoul() and
strtoull().
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-Id: <1487708048-2131-5-git-send-email-armbru@redhat.com>
---
tests/test-cutils.c | 60 ++++++++++++++++++++++++++---------------------------
1 file changed, 30 insertions(+), 30 deletions(-)
diff --git a/tests/test-cutils.c b/tests/test-cutils.c
index 71681dc..749aaa9 100644
--- a/tests/test-cutils.c
+++ b/tests/test-cutils.c
@@ -523,7 +523,7 @@ static void test_qemu_strtoul_correct(void)
err = qemu_strtoul(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, 0);
- g_assert_cmpint(res, ==, 12345);
+ g_assert_cmpuint(res, ==, 12345);
g_assert(endptr == str + 5);
}
@@ -593,7 +593,7 @@ static void test_qemu_strtoul_trailing(void)
err = qemu_strtoul(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, 0);
- g_assert_cmpint(res, ==, 123);
+ g_assert_cmpuint(res, ==, 123);
g_assert(endptr == str + 3);
}
@@ -608,7 +608,7 @@ static void test_qemu_strtoul_octal(void)
err = qemu_strtoul(str, &endptr, 8, &res);
g_assert_cmpint(err, ==, 0);
- g_assert_cmpint(res, ==, 0123);
+ g_assert_cmpuint(res, ==, 0123);
g_assert(endptr == str + strlen(str));
res = 999;
@@ -616,7 +616,7 @@ static void test_qemu_strtoul_octal(void)
err = qemu_strtoul(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, 0);
- g_assert_cmpint(res, ==, 0123);
+ g_assert_cmpuint(res, ==, 0123);
g_assert(endptr == str + strlen(str));
}
@@ -631,7 +631,7 @@ static void test_qemu_strtoul_decimal(void)
err = qemu_strtoul(str, &endptr, 10, &res);
g_assert_cmpint(err, ==, 0);
- g_assert_cmpint(res, ==, 123);
+ g_assert_cmpuint(res, ==, 123);
g_assert(endptr == str + strlen(str));
str = "123";
@@ -640,7 +640,7 @@ static void test_qemu_strtoul_decimal(void)
err = qemu_strtoul(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, 0);
- g_assert_cmpint(res, ==, 123);
+ g_assert_cmpuint(res, ==, 123);
g_assert(endptr == str + strlen(str));
}
@@ -655,7 +655,7 @@ static void test_qemu_strtoul_hex(void)
err = qemu_strtoul(str, &endptr, 16, &res);
g_assert_cmpint(err, ==, 0);
- g_assert_cmpint(res, ==, 0x123);
+ g_assert_cmphex(res, ==, 0x123);
g_assert(endptr == str + strlen(str));
str = "0x123";
@@ -664,7 +664,7 @@ static void test_qemu_strtoul_hex(void)
err = qemu_strtoul(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, 0);
- g_assert_cmpint(res, ==, 0x123);
+ g_assert_cmphex(res, ==, 0x123);
g_assert(endptr == str + strlen(str));
}
@@ -679,7 +679,7 @@ static void test_qemu_strtoul_max(void)
err = qemu_strtoul(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, 0);
- g_assert_cmpint(res, ==, ULONG_MAX);
+ g_assert_cmphex(res, ==, ULONG_MAX);
g_assert(endptr == str + strlen(str));
g_free(str);
}
@@ -695,7 +695,7 @@ static void test_qemu_strtoul_overflow(void)
err = qemu_strtoul(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, -ERANGE);
- g_assert_cmpint(res, ==, ULONG_MAX);
+ g_assert_cmphex(res, ==, ULONG_MAX);
g_assert(endptr == str + strlen(str));
}
@@ -710,7 +710,7 @@ static void test_qemu_strtoul_underflow(void)
err = qemu_strtoul(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, -ERANGE);
- g_assert_cmpint(res, ==, -1ul);
+ g_assert_cmpuint(res, ==, -1ul);
g_assert(endptr == str + strlen(str));
}
@@ -725,7 +725,7 @@ static void test_qemu_strtoul_negative(void)
err = qemu_strtoul(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, 0);
- g_assert_cmpint(res, ==, -321ul);
+ g_assert_cmpuint(res, ==, -321ul);
g_assert(endptr == str + strlen(str));
}
@@ -738,7 +738,7 @@ static void test_qemu_strtoul_full_correct(void)
err = qemu_strtoul(str, NULL, 0, &res);
g_assert_cmpint(err, ==, 0);
- g_assert_cmpint(res, ==, 123);
+ g_assert_cmpuint(res, ==, 123);
}
static void test_qemu_strtoul_full_null(void)
@@ -769,7 +769,7 @@ static void test_qemu_strtoul_full_negative(void)
err = qemu_strtoul(str, NULL, 0, &res);
g_assert_cmpint(err, ==, 0);
- g_assert_cmpint(res, ==, -321ul);
+ g_assert_cmpuint(res, ==, -321ul);
}
static void test_qemu_strtoul_full_trailing(void)
@@ -792,7 +792,7 @@ static void test_qemu_strtoul_full_max(void)
err = qemu_strtoul(str, NULL, 0, &res);
g_assert_cmpint(err, ==, 0);
- g_assert_cmpint(res, ==, ULONG_MAX);
+ g_assert_cmphex(res, ==, ULONG_MAX);
g_free(str);
}
@@ -1094,7 +1094,7 @@ static void test_qemu_strtoull_correct(void)
err = qemu_strtoull(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, 0);
- g_assert_cmpint(res, ==, 12345);
+ g_assert_cmpuint(res, ==, 12345);
g_assert(endptr == str + 5);
}
@@ -1164,7 +1164,7 @@ static void test_qemu_strtoull_trailing(void)
err = qemu_strtoull(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, 0);
- g_assert_cmpint(res, ==, 123);
+ g_assert_cmpuint(res, ==, 123);
g_assert(endptr == str + 3);
}
@@ -1179,7 +1179,7 @@ static void test_qemu_strtoull_octal(void)
err = qemu_strtoull(str, &endptr, 8, &res);
g_assert_cmpint(err, ==, 0);
- g_assert_cmpint(res, ==, 0123);
+ g_assert_cmpuint(res, ==, 0123);
g_assert(endptr == str + strlen(str));
endptr = &f;
@@ -1187,7 +1187,7 @@ static void test_qemu_strtoull_octal(void)
err = qemu_strtoull(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, 0);
- g_assert_cmpint(res, ==, 0123);
+ g_assert_cmpuint(res, ==, 0123);
g_assert(endptr == str + strlen(str));
}
@@ -1202,7 +1202,7 @@ static void test_qemu_strtoull_decimal(void)
err = qemu_strtoull(str, &endptr, 10, &res);
g_assert_cmpint(err, ==, 0);
- g_assert_cmpint(res, ==, 123);
+ g_assert_cmpuint(res, ==, 123);
g_assert(endptr == str + strlen(str));
str = "123";
@@ -1211,7 +1211,7 @@ static void test_qemu_strtoull_decimal(void)
err = qemu_strtoull(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, 0);
- g_assert_cmpint(res, ==, 123);
+ g_assert_cmpuint(res, ==, 123);
g_assert(endptr == str + strlen(str));
}
@@ -1226,7 +1226,7 @@ static void test_qemu_strtoull_hex(void)
err = qemu_strtoull(str, &endptr, 16, &res);
g_assert_cmpint(err, ==, 0);
- g_assert_cmpint(res, ==, 0x123);
+ g_assert_cmphex(res, ==, 0x123);
g_assert(endptr == str + strlen(str));
str = "0x123";
@@ -1235,7 +1235,7 @@ static void test_qemu_strtoull_hex(void)
err = qemu_strtoull(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, 0);
- g_assert_cmpint(res, ==, 0x123);
+ g_assert_cmphex(res, ==, 0x123);
g_assert(endptr == str + strlen(str));
}
@@ -1250,7 +1250,7 @@ static void test_qemu_strtoull_max(void)
err = qemu_strtoull(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, 0);
- g_assert_cmpint(res, ==, ULLONG_MAX);
+ g_assert_cmphex(res, ==, ULLONG_MAX);
g_assert(endptr == str + strlen(str));
g_free(str);
}
@@ -1266,7 +1266,7 @@ static void test_qemu_strtoull_overflow(void)
err = qemu_strtoull(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, -ERANGE);
- g_assert_cmpint(res, ==, ULLONG_MAX);
+ g_assert_cmphex(res, ==, ULLONG_MAX);
g_assert(endptr == str + strlen(str));
}
@@ -1281,7 +1281,7 @@ static void test_qemu_strtoull_underflow(void)
err = qemu_strtoull(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, -ERANGE);
- g_assert_cmpint(res, ==, -1);
+ g_assert_cmphex(res, ==, -1ull);
g_assert(endptr == str + strlen(str));
}
@@ -1296,7 +1296,7 @@ static void test_qemu_strtoull_negative(void)
err = qemu_strtoull(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, 0);
- g_assert_cmpint(res, ==, -321);
+ g_assert_cmpuint(res, ==, -321ull);
g_assert(endptr == str + strlen(str));
}
@@ -1309,7 +1309,7 @@ static void test_qemu_strtoull_full_correct(void)
err = qemu_strtoull(str, NULL, 0, &res);
g_assert_cmpint(err, ==, 0);
- g_assert_cmpint(res, ==, 18446744073709551614LLU);
+ g_assert_cmpuint(res, ==, 18446744073709551614ull);
}
static void test_qemu_strtoull_full_null(void)
@@ -1342,7 +1342,7 @@ static void test_qemu_strtoull_full_negative(void)
err = qemu_strtoull(str, NULL, 0, &res);
g_assert_cmpint(err, ==, 0);
- g_assert_cmpint(res, ==, 18446744073709551295LLU);
+ g_assert_cmpuint(res, ==, -321ull);
}
static void test_qemu_strtoull_full_trailing(void)
@@ -1365,7 +1365,7 @@ static void test_qemu_strtoull_full_max(void)
err = qemu_strtoull(str, NULL, 0, &res);
g_assert_cmpint(err, ==, 0);
- g_assert_cmpint(res, ==, ULLONG_MAX);
+ g_assert_cmphex(res, ==, ULLONG_MAX);
g_free(str);
}
--
2.7.4
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [Qemu-devel] [PULL 05/24] util/cutils: Rewrite documentation of qemu_strtol() & friends
2017-02-23 19:53 [Qemu-devel] [PULL 00/24] option cutils: Fix and clean up number conversions Markus Armbruster
` (3 preceding siblings ...)
2017-02-23 19:53 ` [Qemu-devel] [PULL 04/24] test-cutils: Clean up qemu_strtoul() result checks Markus Armbruster
@ 2017-02-23 19:53 ` Markus Armbruster
2017-02-23 19:53 ` [Qemu-devel] [PULL 06/24] util/cutils: Rename qemu_strtoll(), qemu_strtoull() Markus Armbruster
` (20 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Markus Armbruster @ 2017-02-23 19:53 UTC (permalink / raw)
To: qemu-devel
Fixes the following documentation bugs:
* Fails to document that null @nptr is safe.
* Fails to document that we return -EINVAL when no conversion could be
performed (commit 47d4be1).
* Confuses long long with int64_t, and unsigned long long with
uint64_t.
* Claims the unsigned conversions can underflow. They can't.
While there, mark problematic assumptions that int64_t is long long,
and uint64_t is unsigned long long with FIXME comments.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-Id: <1487708048-2131-6-git-send-email-armbru@redhat.com>
---
util/cutils.c | 80 +++++++++++++++++++++++++++++++++--------------------------
1 file changed, 45 insertions(+), 35 deletions(-)
diff --git a/util/cutils.c b/util/cutils.c
index 4fefcf3..1ae2a08 100644
--- a/util/cutils.c
+++ b/util/cutils.c
@@ -265,9 +265,6 @@ int64_t qemu_strtosz(const char *nptr, char **end)
static int check_strtox_error(const char *p, char *endptr, const char **next,
int err)
{
- /* If no conversion was performed, prefer BSD behavior over glibc
- * behavior.
- */
if (err == 0 && endptr == p) {
err = EINVAL;
}
@@ -281,30 +278,28 @@ static int check_strtox_error(const char *p, char *endptr, const char **next,
}
/**
- * QEMU wrappers for strtol(), strtoll(), strtoul(), strotull() C functions.
+ * Convert string @nptr to a long integer, and store it in @result.
*
- * Convert ASCII string @nptr to a long integer value
- * from the given @base. Parameters @nptr, @endptr, @base
- * follows same semantics as strtol() C function.
+ * This is a wrapper around strtol() that is harder to misuse.
+ * Semantics of @nptr, @endptr, @base match strtol() with differences
+ * noted below.
*
- * Unlike from strtol() function, if @endptr is not NULL, this
- * function will return -EINVAL whenever it cannot fully convert
- * the string in @nptr with given @base to a long. This function returns
- * the result of the conversion only through the @result parameter.
+ * @nptr may be null, and no conversion is performed then.
*
- * If NULL is passed in @endptr, then the whole string in @ntpr
- * is a number otherwise it returns -EINVAL.
+ * If no conversion is performed, store @nptr in *@endptr and return
+ * -EINVAL.
*
- * RETURN VALUE
- * Unlike from strtol() function, this wrapper returns either
- * -EINVAL or the errno set by strtol() function (e.g -ERANGE).
- * If the conversion overflows, -ERANGE is returned, and @result
- * is set to the max value of the desired type
- * (e.g. LONG_MAX, LLONG_MAX, ULONG_MAX, ULLONG_MAX). If the case
- * of underflow, -ERANGE is returned, and @result is set to the min
- * value of the desired type. For strtol(), strtoll(), @result is set to
- * LONG_MIN, LLONG_MIN, respectively, and for strtoul(), strtoull() it
- * is set to 0.
+ * If @endptr is null, and the string isn't fully converted, return
+ * -EINVAL. This is the case when the pointer that would be stored in
+ * a non-null @endptr points to a character other than '\0'.
+ *
+ * If the conversion overflows @result, store LONG_MAX in @result,
+ * and return -ERANGE.
+ *
+ * If the conversion underflows @result, store LONG_MIN in @result,
+ * and return -ERANGE.
+ *
+ * Else store the converted value in @result, and return zero.
*/
int qemu_strtol(const char *nptr, const char **endptr, int base,
long *result)
@@ -325,17 +320,29 @@ int qemu_strtol(const char *nptr, const char **endptr, int base,
}
/**
- * Converts ASCII string to an unsigned long integer.
+ * Convert string @nptr to an unsigned long, and store it in @result.
*
- * If string contains a negative number, value will be converted to
- * the unsigned representation of the signed value, unless the original
- * (nonnegated) value would overflow, in this case, it will set @result
- * to ULONG_MAX, and return ERANGE.
+ * This is a wrapper around strtoul() that is harder to misuse.
+ * Semantics of @nptr, @endptr, @base match strtoul() with differences
+ * noted below.
*
- * The same behavior holds, for qemu_strtoull() but sets @result to
- * ULLONG_MAX instead of ULONG_MAX.
+ * @nptr may be null, and no conversion is performed then.
*
- * See qemu_strtol() documentation for more info.
+ * If no conversion is performed, store @nptr in *@endptr and return
+ * -EINVAL.
+ *
+ * If @endptr is null, and the string isn't fully converted, return
+ * -EINVAL. This is the case when the pointer that would be stored in
+ * a non-null @endptr points to a character other than '\0'.
+ *
+ * If the conversion overflows @result, store ULONG_MAX in @result,
+ * and return -ERANGE.
+ *
+ * Else store the converted value in @result, and return zero.
+ *
+ * Note that a number with a leading minus sign gets converted without
+ * the minus sign, checked for overflow (see above), then negated (in
+ * @result's type). This is exactly how strtoul() works.
*/
int qemu_strtoul(const char *nptr, const char **endptr, int base,
unsigned long *result)
@@ -360,9 +367,10 @@ int qemu_strtoul(const char *nptr, const char **endptr, int base,
}
/**
- * Converts ASCII string to a long long integer.
+ * Convert string @nptr to an int64_t.
*
- * See qemu_strtol() documentation for more info.
+ * Works like qemu_strtol(), except it stores INT64_MAX on overflow,
+ * and INT_MIN on underflow.
*/
int qemu_strtoll(const char *nptr, const char **endptr, int base,
int64_t *result)
@@ -376,6 +384,7 @@ int qemu_strtoll(const char *nptr, const char **endptr, int base,
err = -EINVAL;
} else {
errno = 0;
+ /* FIXME This assumes int64_t is long long */
*result = strtoll(nptr, &p, base);
err = check_strtox_error(nptr, p, endptr, errno);
}
@@ -383,9 +392,9 @@ int qemu_strtoll(const char *nptr, const char **endptr, int base,
}
/**
- * Converts ASCII string to an unsigned long long integer.
+ * Convert string @nptr to an uint64_t.
*
- * See qemu_strtol() documentation for more info.
+ * Works like qemu_strtoul(), except it stores UINT64_MAX on overflow.
*/
int qemu_strtoull(const char *nptr, const char **endptr, int base,
uint64_t *result)
@@ -399,6 +408,7 @@ int qemu_strtoull(const char *nptr, const char **endptr, int base,
err = -EINVAL;
} else {
errno = 0;
+ /* FIXME This assumes uint64_t is unsigned long long */
*result = strtoull(nptr, &p, base);
/* Windows returns 1 for negative out-of-range values. */
if (errno == ERANGE) {
--
2.7.4
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [Qemu-devel] [PULL 06/24] util/cutils: Rename qemu_strtoll(), qemu_strtoull()
2017-02-23 19:53 [Qemu-devel] [PULL 00/24] option cutils: Fix and clean up number conversions Markus Armbruster
` (4 preceding siblings ...)
2017-02-23 19:53 ` [Qemu-devel] [PULL 05/24] util/cutils: Rewrite documentation of qemu_strtol() & friends Markus Armbruster
@ 2017-02-23 19:53 ` Markus Armbruster
2017-02-23 19:53 ` [Qemu-devel] [PULL 07/24] util/cutils: Clean up variable names around qemu_strtol() Markus Armbruster
` (19 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Markus Armbruster @ 2017-02-23 19:53 UTC (permalink / raw)
To: qemu-devel
The name qemu_strtoll() suggests conversion to long long, but it
actually converts to int64_t. Rename to qemu_strtoi64().
The name qemu_strtoull() suggests conversion to unsigned long long,
but it actually converts to uint64_t. Rename to qemu_strtou64().
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-Id: <1487708048-2131-7-git-send-email-armbru@redhat.com>
---
include/qemu/cutils.h | 6 +-
qobject/qdict.c | 2 +-
qtest.c | 34 ++---
tests/test-cutils.c | 366 +++++++++++++++++++++++++++-----------------------
util/cutils.c | 4 +-
util/log.c | 4 +-
6 files changed, 224 insertions(+), 192 deletions(-)
diff --git a/include/qemu/cutils.h b/include/qemu/cutils.h
index 8033929..f922223 100644
--- a/include/qemu/cutils.h
+++ b/include/qemu/cutils.h
@@ -130,9 +130,9 @@ int qemu_strtol(const char *nptr, const char **endptr, int base,
long *result);
int qemu_strtoul(const char *nptr, const char **endptr, int base,
unsigned long *result);
-int qemu_strtoll(const char *nptr, const char **endptr, int base,
- int64_t *result);
-int qemu_strtoull(const char *nptr, const char **endptr, int base,
+int qemu_strtoi64(const char *nptr, const char **endptr, int base,
+ int64_t *result);
+int qemu_strtou64(const char *nptr, const char **endptr, int base,
uint64_t *result);
int parse_uint(const char *s, unsigned long long *value, char **endptr,
diff --git a/qobject/qdict.c b/qobject/qdict.c
index 197b0fb..4be7d3e 100644
--- a/qobject/qdict.c
+++ b/qobject/qdict.c
@@ -767,7 +767,7 @@ static int qdict_is_list(QDict *maybe_list, Error **errp)
for (ent = qdict_first(maybe_list); ent != NULL;
ent = qdict_next(maybe_list, ent)) {
- if (qemu_strtoll(ent->key, NULL, 10, &val) == 0) {
+ if (qemu_strtoi64(ent->key, NULL, 10, &val) == 0) {
if (is_list == -1) {
is_list = 1;
} else if (!is_list) {
diff --git a/qtest.c b/qtest.c
index 1446719..a685827 100644
--- a/qtest.c
+++ b/qtest.c
@@ -373,8 +373,8 @@ static void qtest_process_command(CharBackend *chr, gchar **words)
uint64_t value;
g_assert(words[1] && words[2]);
- g_assert(qemu_strtoull(words[1], NULL, 0, &addr) == 0);
- g_assert(qemu_strtoull(words[2], NULL, 0, &value) == 0);
+ g_assert(qemu_strtou64(words[1], NULL, 0, &addr) == 0);
+ g_assert(qemu_strtou64(words[2], NULL, 0, &value) == 0);
if (words[0][5] == 'b') {
uint8_t data = value;
@@ -402,7 +402,7 @@ static void qtest_process_command(CharBackend *chr, gchar **words)
uint64_t value = UINT64_C(-1);
g_assert(words[1]);
- g_assert(qemu_strtoull(words[1], NULL, 0, &addr) == 0);
+ g_assert(qemu_strtou64(words[1], NULL, 0, &addr) == 0);
if (words[0][4] == 'b') {
uint8_t data;
@@ -428,8 +428,8 @@ static void qtest_process_command(CharBackend *chr, gchar **words)
char *enc;
g_assert(words[1] && words[2]);
- g_assert(qemu_strtoull(words[1], NULL, 0, &addr) == 0);
- g_assert(qemu_strtoull(words[2], NULL, 0, &len) == 0);
+ g_assert(qemu_strtou64(words[1], NULL, 0, &addr) == 0);
+ g_assert(qemu_strtou64(words[2], NULL, 0, &len) == 0);
/* We'd send garbage to libqtest if len is 0 */
g_assert(len);
@@ -452,8 +452,8 @@ static void qtest_process_command(CharBackend *chr, gchar **words)
gchar *b64_data;
g_assert(words[1] && words[2]);
- g_assert(qemu_strtoull(words[1], NULL, 0, &addr) == 0);
- g_assert(qemu_strtoull(words[2], NULL, 0, &len) == 0);
+ g_assert(qemu_strtou64(words[1], NULL, 0, &addr) == 0);
+ g_assert(qemu_strtou64(words[2], NULL, 0, &len) == 0);
data = g_malloc(len);
cpu_physical_memory_read(addr, data, len);
@@ -469,8 +469,8 @@ static void qtest_process_command(CharBackend *chr, gchar **words)
size_t data_len;
g_assert(words[1] && words[2] && words[3]);
- g_assert(qemu_strtoull(words[1], NULL, 0, &addr) == 0);
- g_assert(qemu_strtoull(words[2], NULL, 0, &len) == 0);
+ g_assert(qemu_strtou64(words[1], NULL, 0, &addr) == 0);
+ g_assert(qemu_strtou64(words[2], NULL, 0, &len) == 0);
data_len = strlen(words[3]);
if (data_len < 3) {
@@ -498,8 +498,8 @@ static void qtest_process_command(CharBackend *chr, gchar **words)
unsigned long pattern;
g_assert(words[1] && words[2] && words[3]);
- g_assert(qemu_strtoull(words[1], NULL, 0, &addr) == 0);
- g_assert(qemu_strtoull(words[2], NULL, 0, &len) == 0);
+ g_assert(qemu_strtou64(words[1], NULL, 0, &addr) == 0);
+ g_assert(qemu_strtou64(words[2], NULL, 0, &len) == 0);
g_assert(qemu_strtoul(words[3], NULL, 0, &pattern) == 0);
if (len) {
@@ -518,8 +518,8 @@ static void qtest_process_command(CharBackend *chr, gchar **words)
gsize out_len;
g_assert(words[1] && words[2] && words[3]);
- g_assert(qemu_strtoull(words[1], NULL, 0, &addr) == 0);
- g_assert(qemu_strtoull(words[2], NULL, 0, &len) == 0);
+ g_assert(qemu_strtou64(words[1], NULL, 0, &addr) == 0);
+ g_assert(qemu_strtou64(words[2], NULL, 0, &len) == 0);
data_len = strlen(words[3]);
if (data_len < 3) {
@@ -552,9 +552,9 @@ static void qtest_process_command(CharBackend *chr, gchar **words)
unsigned long nargs, nret;
g_assert(qemu_strtoul(words[2], NULL, 0, &nargs) == 0);
- g_assert(qemu_strtoull(words[3], NULL, 0, &args) == 0);
+ g_assert(qemu_strtou64(words[3], NULL, 0, &args) == 0);
g_assert(qemu_strtoul(words[4], NULL, 0, &nret) == 0);
- g_assert(qemu_strtoull(words[5], NULL, 0, &ret) == 0);
+ g_assert(qemu_strtou64(words[5], NULL, 0, &ret) == 0);
res = qtest_rtas_call(words[1], nargs, args, nret, ret);
qtest_send_prefix(chr);
@@ -564,7 +564,7 @@ static void qtest_process_command(CharBackend *chr, gchar **words)
int64_t ns;
if (words[1]) {
- g_assert(qemu_strtoll(words[1], NULL, 0, &ns) == 0);
+ g_assert(qemu_strtoi64(words[1], NULL, 0, &ns) == 0);
} else {
ns = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
}
@@ -576,7 +576,7 @@ static void qtest_process_command(CharBackend *chr, gchar **words)
int64_t ns;
g_assert(words[1]);
- g_assert(qemu_strtoll(words[1], NULL, 0, &ns) == 0);
+ g_assert(qemu_strtoi64(words[1], NULL, 0, &ns) == 0);
qtest_clock_warp(ns);
qtest_send_prefix(chr);
qtest_sendf(chr, "OK %"PRIi64"\n",
diff --git a/tests/test-cutils.c b/tests/test-cutils.c
index 749aaa9..185b023 100644
--- a/tests/test-cutils.c
+++ b/tests/test-cutils.c
@@ -796,7 +796,7 @@ static void test_qemu_strtoul_full_max(void)
g_free(str);
}
-static void test_qemu_strtoll_correct(void)
+static void test_qemu_strtoi64_correct(void)
{
const char *str = "12345 foo";
char f = 'X';
@@ -804,27 +804,27 @@ static void test_qemu_strtoll_correct(void)
int64_t res = 999;
int err;
- err = qemu_strtoll(str, &endptr, 0, &res);
+ err = qemu_strtoi64(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 12345);
g_assert(endptr == str + 5);
}
-static void test_qemu_strtoll_null(void)
+static void test_qemu_strtoi64_null(void)
{
char f = 'X';
const char *endptr = &f;
int64_t res = 999;
int err;
- err = qemu_strtoll(NULL, &endptr, 0, &res);
+ err = qemu_strtoi64(NULL, &endptr, 0, &res);
g_assert_cmpint(err, ==, -EINVAL);
g_assert(endptr == NULL);
}
-static void test_qemu_strtoll_empty(void)
+static void test_qemu_strtoi64_empty(void)
{
const char *str = "";
char f = 'X';
@@ -832,13 +832,13 @@ static void test_qemu_strtoll_empty(void)
int64_t res = 999;
int err;
- err = qemu_strtoll(str, &endptr, 0, &res);
+ err = qemu_strtoi64(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, -EINVAL);
g_assert(endptr == str);
}
-static void test_qemu_strtoll_whitespace(void)
+static void test_qemu_strtoi64_whitespace(void)
{
const char *str = " \t ";
char f = 'X';
@@ -846,13 +846,13 @@ static void test_qemu_strtoll_whitespace(void)
int64_t res = 999;
int err;
- err = qemu_strtoll(str, &endptr, 0, &res);
+ err = qemu_strtoi64(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, -EINVAL);
g_assert(endptr == str);
}
-static void test_qemu_strtoll_invalid(void)
+static void test_qemu_strtoi64_invalid(void)
{
const char *str = " xxxx \t abc";
char f = 'X';
@@ -860,13 +860,13 @@ static void test_qemu_strtoll_invalid(void)
int64_t res = 999;
int err;
- err = qemu_strtoll(str, &endptr, 0, &res);
+ err = qemu_strtoi64(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, -EINVAL);
g_assert(endptr == str);
}
-static void test_qemu_strtoll_trailing(void)
+static void test_qemu_strtoi64_trailing(void)
{
const char *str = "123xxx";
char f = 'X';
@@ -874,14 +874,14 @@ static void test_qemu_strtoll_trailing(void)
int64_t res = 999;
int err;
- err = qemu_strtoll(str, &endptr, 0, &res);
+ err = qemu_strtoi64(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 123);
g_assert(endptr == str + 3);
}
-static void test_qemu_strtoll_octal(void)
+static void test_qemu_strtoi64_octal(void)
{
const char *str = "0123";
char f = 'X';
@@ -889,7 +889,7 @@ static void test_qemu_strtoll_octal(void)
int64_t res = 999;
int err;
- err = qemu_strtoll(str, &endptr, 8, &res);
+ err = qemu_strtoi64(str, &endptr, 8, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 0123);
@@ -897,14 +897,14 @@ static void test_qemu_strtoll_octal(void)
endptr = &f;
res = 999;
- err = qemu_strtoll(str, &endptr, 0, &res);
+ err = qemu_strtoi64(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 0123);
g_assert(endptr == str + strlen(str));
}
-static void test_qemu_strtoll_decimal(void)
+static void test_qemu_strtoi64_decimal(void)
{
const char *str = "0123";
char f = 'X';
@@ -912,7 +912,7 @@ static void test_qemu_strtoll_decimal(void)
int64_t res = 999;
int err;
- err = qemu_strtoll(str, &endptr, 10, &res);
+ err = qemu_strtoi64(str, &endptr, 10, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 123);
@@ -921,14 +921,14 @@ static void test_qemu_strtoll_decimal(void)
str = "123";
endptr = &f;
res = 999;
- err = qemu_strtoll(str, &endptr, 0, &res);
+ err = qemu_strtoi64(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 123);
g_assert(endptr == str + strlen(str));
}
-static void test_qemu_strtoll_hex(void)
+static void test_qemu_strtoi64_hex(void)
{
const char *str = "0123";
char f = 'X';
@@ -936,7 +936,7 @@ static void test_qemu_strtoll_hex(void)
int64_t res = 999;
int err;
- err = qemu_strtoll(str, &endptr, 16, &res);
+ err = qemu_strtoi64(str, &endptr, 16, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 0x123);
@@ -945,14 +945,14 @@ static void test_qemu_strtoll_hex(void)
str = "0x123";
endptr = &f;
res = 999;
- err = qemu_strtoll(str, &endptr, 0, &res);
+ err = qemu_strtoi64(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 0x123);
g_assert(endptr == str + strlen(str));
}
-static void test_qemu_strtoll_max(void)
+static void test_qemu_strtoi64_max(void)
{
char *str = g_strdup_printf("%lld", LLONG_MAX);
char f = 'X';
@@ -960,7 +960,7 @@ static void test_qemu_strtoll_max(void)
int64_t res = 999;
int err;
- err = qemu_strtoll(str, &endptr, 0, &res);
+ err = qemu_strtoi64(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, LLONG_MAX);
@@ -968,7 +968,7 @@ static void test_qemu_strtoll_max(void)
g_free(str);
}
-static void test_qemu_strtoll_overflow(void)
+static void test_qemu_strtoi64_overflow(void)
{
const char *str = "99999999999999999999999999999999999999999999";
char f = 'X';
@@ -976,14 +976,14 @@ static void test_qemu_strtoll_overflow(void)
int64_t res = 999;
int err;
- err = qemu_strtoll(str, &endptr, 0, &res);
+ err = qemu_strtoi64(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, -ERANGE);
g_assert_cmpint(res, ==, LLONG_MAX);
g_assert(endptr == str + strlen(str));
}
-static void test_qemu_strtoll_underflow(void)
+static void test_qemu_strtoi64_underflow(void)
{
const char *str = "-99999999999999999999999999999999999999999999";
char f = 'X';
@@ -991,14 +991,14 @@ static void test_qemu_strtoll_underflow(void)
int64_t res = 999;
int err;
- err = qemu_strtoll(str, &endptr, 0, &res);
+ err = qemu_strtoi64(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, -ERANGE);
g_assert_cmpint(res, ==, LLONG_MIN);
g_assert(endptr == str + strlen(str));
}
-static void test_qemu_strtoll_negative(void)
+static void test_qemu_strtoi64_negative(void)
{
const char *str = " \t -321";
char f = 'X';
@@ -1006,84 +1006,84 @@ static void test_qemu_strtoll_negative(void)
int64_t res = 999;
int err;
- err = qemu_strtoll(str, &endptr, 0, &res);
+ err = qemu_strtoi64(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, -321);
g_assert(endptr == str + strlen(str));
}
-static void test_qemu_strtoll_full_correct(void)
+static void test_qemu_strtoi64_full_correct(void)
{
const char *str = "123";
int64_t res = 999;
int err;
- err = qemu_strtoll(str, NULL, 0, &res);
+ err = qemu_strtoi64(str, NULL, 0, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 123);
}
-static void test_qemu_strtoll_full_null(void)
+static void test_qemu_strtoi64_full_null(void)
{
int64_t res = 999;
int err;
- err = qemu_strtoll(NULL, NULL, 0, &res);
+ err = qemu_strtoi64(NULL, NULL, 0, &res);
g_assert_cmpint(err, ==, -EINVAL);
}
-static void test_qemu_strtoll_full_empty(void)
+static void test_qemu_strtoi64_full_empty(void)
{
const char *str = "";
int64_t res = 999;
int err;
- err = qemu_strtoll(str, NULL, 0, &res);
+ err = qemu_strtoi64(str, NULL, 0, &res);
g_assert_cmpint(err, ==, -EINVAL);
}
-static void test_qemu_strtoll_full_negative(void)
+static void test_qemu_strtoi64_full_negative(void)
{
const char *str = " \t -321";
int64_t res = 999;
int err;
- err = qemu_strtoll(str, NULL, 0, &res);
+ err = qemu_strtoi64(str, NULL, 0, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, -321);
}
-static void test_qemu_strtoll_full_trailing(void)
+static void test_qemu_strtoi64_full_trailing(void)
{
const char *str = "123xxx";
int64_t res = 999;
int err;
- err = qemu_strtoll(str, NULL, 0, &res);
+ err = qemu_strtoi64(str, NULL, 0, &res);
g_assert_cmpint(err, ==, -EINVAL);
}
-static void test_qemu_strtoll_full_max(void)
+static void test_qemu_strtoi64_full_max(void)
{
char *str = g_strdup_printf("%lld", LLONG_MAX);
int64_t res;
int err;
- err = qemu_strtoll(str, NULL, 0, &res);
+ err = qemu_strtoi64(str, NULL, 0, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, LLONG_MAX);
g_free(str);
}
-static void test_qemu_strtoull_correct(void)
+static void test_qemu_strtou64_correct(void)
{
const char *str = "12345 foo";
char f = 'X';
@@ -1091,27 +1091,27 @@ static void test_qemu_strtoull_correct(void)
uint64_t res = 999;
int err;
- err = qemu_strtoull(str, &endptr, 0, &res);
+ err = qemu_strtou64(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpuint(res, ==, 12345);
g_assert(endptr == str + 5);
}
-static void test_qemu_strtoull_null(void)
+static void test_qemu_strtou64_null(void)
{
char f = 'X';
const char *endptr = &f;
uint64_t res = 999;
int err;
- err = qemu_strtoull(NULL, &endptr, 0, &res);
+ err = qemu_strtou64(NULL, &endptr, 0, &res);
g_assert_cmpint(err, ==, -EINVAL);
g_assert(endptr == NULL);
}
-static void test_qemu_strtoull_empty(void)
+static void test_qemu_strtou64_empty(void)
{
const char *str = "";
char f = 'X';
@@ -1119,13 +1119,13 @@ static void test_qemu_strtoull_empty(void)
uint64_t res = 999;
int err;
- err = qemu_strtoull(str, &endptr, 0, &res);
+ err = qemu_strtou64(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, -EINVAL);
g_assert(endptr == str);
}
-static void test_qemu_strtoull_whitespace(void)
+static void test_qemu_strtou64_whitespace(void)
{
const char *str = " \t ";
char f = 'X';
@@ -1133,13 +1133,13 @@ static void test_qemu_strtoull_whitespace(void)
uint64_t res = 999;
int err;
- err = qemu_strtoull(str, &endptr, 0, &res);
+ err = qemu_strtou64(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, -EINVAL);
g_assert(endptr == str);
}
-static void test_qemu_strtoull_invalid(void)
+static void test_qemu_strtou64_invalid(void)
{
const char *str = " xxxx \t abc";
char f = 'X';
@@ -1147,13 +1147,13 @@ static void test_qemu_strtoull_invalid(void)
uint64_t res = 999;
int err;
- err = qemu_strtoull(str, &endptr, 0, &res);
+ err = qemu_strtou64(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, -EINVAL);
g_assert(endptr == str);
}
-static void test_qemu_strtoull_trailing(void)
+static void test_qemu_strtou64_trailing(void)
{
const char *str = "123xxx";
char f = 'X';
@@ -1161,14 +1161,14 @@ static void test_qemu_strtoull_trailing(void)
uint64_t res = 999;
int err;
- err = qemu_strtoull(str, &endptr, 0, &res);
+ err = qemu_strtou64(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpuint(res, ==, 123);
g_assert(endptr == str + 3);
}
-static void test_qemu_strtoull_octal(void)
+static void test_qemu_strtou64_octal(void)
{
const char *str = "0123";
char f = 'X';
@@ -1176,7 +1176,7 @@ static void test_qemu_strtoull_octal(void)
uint64_t res = 999;
int err;
- err = qemu_strtoull(str, &endptr, 8, &res);
+ err = qemu_strtou64(str, &endptr, 8, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpuint(res, ==, 0123);
@@ -1184,14 +1184,14 @@ static void test_qemu_strtoull_octal(void)
endptr = &f;
res = 999;
- err = qemu_strtoull(str, &endptr, 0, &res);
+ err = qemu_strtou64(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpuint(res, ==, 0123);
g_assert(endptr == str + strlen(str));
}
-static void test_qemu_strtoull_decimal(void)
+static void test_qemu_strtou64_decimal(void)
{
const char *str = "0123";
char f = 'X';
@@ -1199,7 +1199,7 @@ static void test_qemu_strtoull_decimal(void)
uint64_t res = 999;
int err;
- err = qemu_strtoull(str, &endptr, 10, &res);
+ err = qemu_strtou64(str, &endptr, 10, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpuint(res, ==, 123);
@@ -1208,14 +1208,14 @@ static void test_qemu_strtoull_decimal(void)
str = "123";
endptr = &f;
res = 999;
- err = qemu_strtoull(str, &endptr, 0, &res);
+ err = qemu_strtou64(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpuint(res, ==, 123);
g_assert(endptr == str + strlen(str));
}
-static void test_qemu_strtoull_hex(void)
+static void test_qemu_strtou64_hex(void)
{
const char *str = "0123";
char f = 'X';
@@ -1223,7 +1223,7 @@ static void test_qemu_strtoull_hex(void)
uint64_t res = 999;
int err;
- err = qemu_strtoull(str, &endptr, 16, &res);
+ err = qemu_strtou64(str, &endptr, 16, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmphex(res, ==, 0x123);
@@ -1232,14 +1232,14 @@ static void test_qemu_strtoull_hex(void)
str = "0x123";
endptr = &f;
res = 999;
- err = qemu_strtoull(str, &endptr, 0, &res);
+ err = qemu_strtou64(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmphex(res, ==, 0x123);
g_assert(endptr == str + strlen(str));
}
-static void test_qemu_strtoull_max(void)
+static void test_qemu_strtou64_max(void)
{
char *str = g_strdup_printf("%llu", ULLONG_MAX);
char f = 'X';
@@ -1247,7 +1247,7 @@ static void test_qemu_strtoull_max(void)
uint64_t res = 999;
int err;
- err = qemu_strtoull(str, &endptr, 0, &res);
+ err = qemu_strtou64(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmphex(res, ==, ULLONG_MAX);
@@ -1255,7 +1255,7 @@ static void test_qemu_strtoull_max(void)
g_free(str);
}
-static void test_qemu_strtoull_overflow(void)
+static void test_qemu_strtou64_overflow(void)
{
const char *str = "99999999999999999999999999999999999999999999";
char f = 'X';
@@ -1263,14 +1263,14 @@ static void test_qemu_strtoull_overflow(void)
uint64_t res = 999;
int err;
- err = qemu_strtoull(str, &endptr, 0, &res);
+ err = qemu_strtou64(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, -ERANGE);
g_assert_cmphex(res, ==, ULLONG_MAX);
g_assert(endptr == str + strlen(str));
}
-static void test_qemu_strtoull_underflow(void)
+static void test_qemu_strtou64_underflow(void)
{
const char *str = "-99999999999999999999999999999999999999999999";
char f = 'X';
@@ -1278,14 +1278,14 @@ static void test_qemu_strtoull_underflow(void)
uint64_t res = 999;
int err;
- err = qemu_strtoull(str, &endptr, 0, &res);
+ err = qemu_strtou64(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, -ERANGE);
g_assert_cmphex(res, ==, -1ull);
g_assert(endptr == str + strlen(str));
}
-static void test_qemu_strtoull_negative(void)
+static void test_qemu_strtou64_negative(void)
{
const char *str = " \t -321";
char f = 'X';
@@ -1293,76 +1293,76 @@ static void test_qemu_strtoull_negative(void)
uint64_t res = 999;
int err;
- err = qemu_strtoull(str, &endptr, 0, &res);
+ err = qemu_strtou64(str, &endptr, 0, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpuint(res, ==, -321ull);
g_assert(endptr == str + strlen(str));
}
-static void test_qemu_strtoull_full_correct(void)
+static void test_qemu_strtou64_full_correct(void)
{
const char *str = "18446744073709551614";
uint64_t res = 999;
int err;
- err = qemu_strtoull(str, NULL, 0, &res);
+ err = qemu_strtou64(str, NULL, 0, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpuint(res, ==, 18446744073709551614ull);
}
-static void test_qemu_strtoull_full_null(void)
+static void test_qemu_strtou64_full_null(void)
{
uint64_t res = 999;
int err;
- err = qemu_strtoull(NULL, NULL, 0, &res);
+ err = qemu_strtou64(NULL, NULL, 0, &res);
g_assert_cmpint(err, ==, -EINVAL);
}
-static void test_qemu_strtoull_full_empty(void)
+static void test_qemu_strtou64_full_empty(void)
{
const char *str = "";
uint64_t res = 999;
int err;
- err = qemu_strtoull(str, NULL, 0, &res);
+ err = qemu_strtou64(str, NULL, 0, &res);
g_assert_cmpint(err, ==, -EINVAL);
}
-static void test_qemu_strtoull_full_negative(void)
+static void test_qemu_strtou64_full_negative(void)
{
const char *str = " \t -321";
uint64_t res = 999;
int err;
- err = qemu_strtoull(str, NULL, 0, &res);
+ err = qemu_strtou64(str, NULL, 0, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpuint(res, ==, -321ull);
}
-static void test_qemu_strtoull_full_trailing(void)
+static void test_qemu_strtou64_full_trailing(void)
{
const char *str = "18446744073709551614xxxxxx";
uint64_t res = 999;
int err;
- err = qemu_strtoull(str, NULL, 0, &res);
+ err = qemu_strtou64(str, NULL, 0, &res);
g_assert_cmpint(err, ==, -EINVAL);
}
-static void test_qemu_strtoull_full_max(void)
+static void test_qemu_strtou64_full_max(void)
{
char *str = g_strdup_printf("%lld", ULLONG_MAX);
uint64_t res = 999;
int err;
- err = qemu_strtoull(str, NULL, 0, &res);
+ err = qemu_strtou64(str, NULL, 0, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmphex(res, ==, ULLONG_MAX);
@@ -1471,21 +1471,32 @@ int main(int argc, char **argv)
test_parse_uint_full_correct);
/* qemu_strtol() tests */
- g_test_add_func("/cutils/qemu_strtol/correct", test_qemu_strtol_correct);
- g_test_add_func("/cutils/qemu_strtol/null", test_qemu_strtol_null);
- g_test_add_func("/cutils/qemu_strtol/empty", test_qemu_strtol_empty);
+ g_test_add_func("/cutils/qemu_strtol/correct",
+ test_qemu_strtol_correct);
+ g_test_add_func("/cutils/qemu_strtol/null",
+ test_qemu_strtol_null);
+ g_test_add_func("/cutils/qemu_strtol/empty",
+ test_qemu_strtol_empty);
g_test_add_func("/cutils/qemu_strtol/whitespace",
test_qemu_strtol_whitespace);
- g_test_add_func("/cutils/qemu_strtol/invalid", test_qemu_strtol_invalid);
- g_test_add_func("/cutils/qemu_strtol/trailing", test_qemu_strtol_trailing);
- g_test_add_func("/cutils/qemu_strtol/octal", test_qemu_strtol_octal);
- g_test_add_func("/cutils/qemu_strtol/decimal", test_qemu_strtol_decimal);
- g_test_add_func("/cutils/qemu_strtol/hex", test_qemu_strtol_hex);
- g_test_add_func("/cutils/qemu_strtol/max", test_qemu_strtol_max);
- g_test_add_func("/cutils/qemu_strtol/overflow", test_qemu_strtol_overflow);
+ g_test_add_func("/cutils/qemu_strtol/invalid",
+ test_qemu_strtol_invalid);
+ g_test_add_func("/cutils/qemu_strtol/trailing",
+ test_qemu_strtol_trailing);
+ g_test_add_func("/cutils/qemu_strtol/octal",
+ test_qemu_strtol_octal);
+ g_test_add_func("/cutils/qemu_strtol/decimal",
+ test_qemu_strtol_decimal);
+ g_test_add_func("/cutils/qemu_strtol/hex",
+ test_qemu_strtol_hex);
+ g_test_add_func("/cutils/qemu_strtol/max",
+ test_qemu_strtol_max);
+ g_test_add_func("/cutils/qemu_strtol/overflow",
+ test_qemu_strtol_overflow);
g_test_add_func("/cutils/qemu_strtol/underflow",
test_qemu_strtol_underflow);
- g_test_add_func("/cutils/qemu_strtol/negative", test_qemu_strtol_negative);
+ g_test_add_func("/cutils/qemu_strtol/negative",
+ test_qemu_strtol_negative);
g_test_add_func("/cutils/qemu_strtol_full/correct",
test_qemu_strtol_full_correct);
g_test_add_func("/cutils/qemu_strtol_full/null",
@@ -1500,18 +1511,26 @@ int main(int argc, char **argv)
test_qemu_strtol_full_max);
/* qemu_strtoul() tests */
- g_test_add_func("/cutils/qemu_strtoul/correct", test_qemu_strtoul_correct);
- g_test_add_func("/cutils/qemu_strtoul/null", test_qemu_strtoul_null);
- g_test_add_func("/cutils/qemu_strtoul/empty", test_qemu_strtoul_empty);
+ g_test_add_func("/cutils/qemu_strtoul/correct",
+ test_qemu_strtoul_correct);
+ g_test_add_func("/cutils/qemu_strtoul/null",
+ test_qemu_strtoul_null);
+ g_test_add_func("/cutils/qemu_strtoul/empty",
+ test_qemu_strtoul_empty);
g_test_add_func("/cutils/qemu_strtoul/whitespace",
test_qemu_strtoul_whitespace);
- g_test_add_func("/cutils/qemu_strtoul/invalid", test_qemu_strtoul_invalid);
+ g_test_add_func("/cutils/qemu_strtoul/invalid",
+ test_qemu_strtoul_invalid);
g_test_add_func("/cutils/qemu_strtoul/trailing",
test_qemu_strtoul_trailing);
- g_test_add_func("/cutils/qemu_strtoul/octal", test_qemu_strtoul_octal);
- g_test_add_func("/cutils/qemu_strtoul/decimal", test_qemu_strtoul_decimal);
- g_test_add_func("/cutils/qemu_strtoul/hex", test_qemu_strtoul_hex);
- g_test_add_func("/cutils/qemu_strtoul/max", test_qemu_strtoul_max);
+ g_test_add_func("/cutils/qemu_strtoul/octal",
+ test_qemu_strtoul_octal);
+ g_test_add_func("/cutils/qemu_strtoul/decimal",
+ test_qemu_strtoul_decimal);
+ g_test_add_func("/cutils/qemu_strtoul/hex",
+ test_qemu_strtoul_hex);
+ g_test_add_func("/cutils/qemu_strtoul/max",
+ test_qemu_strtoul_max);
g_test_add_func("/cutils/qemu_strtoul/overflow",
test_qemu_strtoul_overflow);
g_test_add_func("/cutils/qemu_strtoul/underflow",
@@ -1531,73 +1550,86 @@ int main(int argc, char **argv)
g_test_add_func("/cutils/qemu_strtoul_full/max",
test_qemu_strtoul_full_max);
- /* qemu_strtoll() tests */
- g_test_add_func("/cutils/qemu_strtoll/correct", test_qemu_strtoll_correct);
- g_test_add_func("/cutils/qemu_strtoll/null", test_qemu_strtoll_null);
- g_test_add_func("/cutils/qemu_strtoll/empty", test_qemu_strtoll_empty);
- g_test_add_func("/cutils/qemu_strtoll/whitespace",
- test_qemu_strtoll_whitespace);
- g_test_add_func("/cutils/qemu_strtoll/invalid", test_qemu_strtoll_invalid);
- g_test_add_func("/cutils/qemu_strtoll/trailing",
- test_qemu_strtoll_trailing);
- g_test_add_func("/cutils/qemu_strtoll/octal", test_qemu_strtoll_octal);
- g_test_add_func("/cutils/qemu_strtoll/decimal", test_qemu_strtoll_decimal);
- g_test_add_func("/cutils/qemu_strtoll/hex", test_qemu_strtoll_hex);
- g_test_add_func("/cutils/qemu_strtoll/max", test_qemu_strtoll_max);
- g_test_add_func("/cutils/qemu_strtoll/overflow",
- test_qemu_strtoll_overflow);
- g_test_add_func("/cutils/qemu_strtoll/underflow",
- test_qemu_strtoll_underflow);
- g_test_add_func("/cutils/qemu_strtoll/negative",
- test_qemu_strtoll_negative);
- g_test_add_func("/cutils/qemu_strtoll_full/correct",
- test_qemu_strtoll_full_correct);
- g_test_add_func("/cutils/qemu_strtoll_full/null",
- test_qemu_strtoll_full_null);
- g_test_add_func("/cutils/qemu_strtoll_full/empty",
- test_qemu_strtoll_full_empty);
- g_test_add_func("/cutils/qemu_strtoll_full/negative",
- test_qemu_strtoll_full_negative);
- g_test_add_func("/cutils/qemu_strtoll_full/trailing",
- test_qemu_strtoll_full_trailing);
- g_test_add_func("/cutils/qemu_strtoll_full/max",
- test_qemu_strtoll_full_max);
+ /* qemu_strtoi64() tests */
+ g_test_add_func("/cutils/qemu_strtoi64/correct",
+ test_qemu_strtoi64_correct);
+ g_test_add_func("/cutils/qemu_strtoi64/null",
+ test_qemu_strtoi64_null);
+ g_test_add_func("/cutils/qemu_strtoi64/empty",
+ test_qemu_strtoi64_empty);
+ g_test_add_func("/cutils/qemu_strtoi64/whitespace",
+ test_qemu_strtoi64_whitespace);
+ g_test_add_func("/cutils/qemu_strtoi64/invalid"
+ ,
+ test_qemu_strtoi64_invalid);
+ g_test_add_func("/cutils/qemu_strtoi64/trailing",
+ test_qemu_strtoi64_trailing);
+ g_test_add_func("/cutils/qemu_strtoi64/octal",
+ test_qemu_strtoi64_octal);
+ g_test_add_func("/cutils/qemu_strtoi64/decimal",
+ test_qemu_strtoi64_decimal);
+ g_test_add_func("/cutils/qemu_strtoi64/hex",
+ test_qemu_strtoi64_hex);
+ g_test_add_func("/cutils/qemu_strtoi64/max",
+ test_qemu_strtoi64_max);
+ g_test_add_func("/cutils/qemu_strtoi64/overflow",
+ test_qemu_strtoi64_overflow);
+ g_test_add_func("/cutils/qemu_strtoi64/underflow",
+ test_qemu_strtoi64_underflow);
+ g_test_add_func("/cutils/qemu_strtoi64/negative",
+ test_qemu_strtoi64_negative);
+ g_test_add_func("/cutils/qemu_strtoi64_full/correct",
+ test_qemu_strtoi64_full_correct);
+ g_test_add_func("/cutils/qemu_strtoi64_full/null",
+ test_qemu_strtoi64_full_null);
+ g_test_add_func("/cutils/qemu_strtoi64_full/empty",
+ test_qemu_strtoi64_full_empty);
+ g_test_add_func("/cutils/qemu_strtoi64_full/negative",
+ test_qemu_strtoi64_full_negative);
+ g_test_add_func("/cutils/qemu_strtoi64_full/trailing",
+ test_qemu_strtoi64_full_trailing);
+ g_test_add_func("/cutils/qemu_strtoi64_full/max",
+ test_qemu_strtoi64_full_max);
- /* qemu_strtoull() tests */
- g_test_add_func("/cutils/qemu_strtoull/correct",
- test_qemu_strtoull_correct);
- g_test_add_func("/cutils/qemu_strtoull/null",
- test_qemu_strtoull_null);
- g_test_add_func("/cutils/qemu_strtoull/empty", test_qemu_strtoull_empty);
- g_test_add_func("/cutils/qemu_strtoull/whitespace",
- test_qemu_strtoull_whitespace);
- g_test_add_func("/cutils/qemu_strtoull/invalid",
- test_qemu_strtoull_invalid);
- g_test_add_func("/cutils/qemu_strtoull/trailing",
- test_qemu_strtoull_trailing);
- g_test_add_func("/cutils/qemu_strtoull/octal", test_qemu_strtoull_octal);
- g_test_add_func("/cutils/qemu_strtoull/decimal",
- test_qemu_strtoull_decimal);
- g_test_add_func("/cutils/qemu_strtoull/hex", test_qemu_strtoull_hex);
- g_test_add_func("/cutils/qemu_strtoull/max", test_qemu_strtoull_max);
- g_test_add_func("/cutils/qemu_strtoull/overflow",
- test_qemu_strtoull_overflow);
- g_test_add_func("/cutils/qemu_strtoull/underflow",
- test_qemu_strtoull_underflow);
- g_test_add_func("/cutils/qemu_strtoull/negative",
- test_qemu_strtoull_negative);
- g_test_add_func("/cutils/qemu_strtoull_full/correct",
- test_qemu_strtoull_full_correct);
- g_test_add_func("/cutils/qemu_strtoull_full/null",
- test_qemu_strtoull_full_null);
- g_test_add_func("/cutils/qemu_strtoull_full/empty",
- test_qemu_strtoull_full_empty);
- g_test_add_func("/cutils/qemu_strtoull_full/negative",
- test_qemu_strtoull_full_negative);
- g_test_add_func("/cutils/qemu_strtoull_full/trailing",
- test_qemu_strtoull_full_trailing);
- g_test_add_func("/cutils/qemu_strtoull_full/max",
- test_qemu_strtoull_full_max);
+ /* qemu_strtou64() tests */
+ g_test_add_func("/cutils/qemu_strtou64/correct",
+ test_qemu_strtou64_correct);
+ g_test_add_func("/cutils/qemu_strtou64/null",
+ test_qemu_strtou64_null);
+ g_test_add_func("/cutils/qemu_strtou64/empty",
+ test_qemu_strtou64_empty);
+ g_test_add_func("/cutils/qemu_strtou64/whitespace",
+ test_qemu_strtou64_whitespace);
+ g_test_add_func("/cutils/qemu_strtou64/invalid",
+ test_qemu_strtou64_invalid);
+ g_test_add_func("/cutils/qemu_strtou64/trailing",
+ test_qemu_strtou64_trailing);
+ g_test_add_func("/cutils/qemu_strtou64/octal",
+ test_qemu_strtou64_octal);
+ g_test_add_func("/cutils/qemu_strtou64/decimal",
+ test_qemu_strtou64_decimal);
+ g_test_add_func("/cutils/qemu_strtou64/hex",
+ test_qemu_strtou64_hex);
+ g_test_add_func("/cutils/qemu_strtou64/max",
+ test_qemu_strtou64_max);
+ g_test_add_func("/cutils/qemu_strtou64/overflow",
+ test_qemu_strtou64_overflow);
+ g_test_add_func("/cutils/qemu_strtou64/underflow",
+ test_qemu_strtou64_underflow);
+ g_test_add_func("/cutils/qemu_strtou64/negative",
+ test_qemu_strtou64_negative);
+ g_test_add_func("/cutils/qemu_strtou64_full/correct",
+ test_qemu_strtou64_full_correct);
+ g_test_add_func("/cutils/qemu_strtou64_full/null",
+ test_qemu_strtou64_full_null);
+ g_test_add_func("/cutils/qemu_strtou64_full/empty",
+ test_qemu_strtou64_full_empty);
+ g_test_add_func("/cutils/qemu_strtou64_full/negative",
+ test_qemu_strtou64_full_negative);
+ g_test_add_func("/cutils/qemu_strtou64_full/trailing",
+ test_qemu_strtou64_full_trailing);
+ g_test_add_func("/cutils/qemu_strtou64_full/max",
+ test_qemu_strtou64_full_max);
g_test_add_func("/cutils/strtosz/simple",
test_qemu_strtosz_simple);
diff --git a/util/cutils.c b/util/cutils.c
index 1ae2a08..0dc9b28 100644
--- a/util/cutils.c
+++ b/util/cutils.c
@@ -372,7 +372,7 @@ int qemu_strtoul(const char *nptr, const char **endptr, int base,
* Works like qemu_strtol(), except it stores INT64_MAX on overflow,
* and INT_MIN on underflow.
*/
-int qemu_strtoll(const char *nptr, const char **endptr, int base,
+int qemu_strtoi64(const char *nptr, const char **endptr, int base,
int64_t *result)
{
char *p;
@@ -396,7 +396,7 @@ int qemu_strtoll(const char *nptr, const char **endptr, int base,
*
* Works like qemu_strtoul(), except it stores UINT64_MAX on overflow.
*/
-int qemu_strtoull(const char *nptr, const char **endptr, int base,
+int qemu_strtou64(const char *nptr, const char **endptr, int base,
uint64_t *result)
{
char *p;
diff --git a/util/log.c b/util/log.c
index e077340..96f30dd 100644
--- a/util/log.c
+++ b/util/log.c
@@ -183,13 +183,13 @@ void qemu_set_dfilter_ranges(const char *filter_spec, Error **errp)
goto out;
}
- if (qemu_strtoull(r, &e, 0, &r1val)
+ if (qemu_strtou64(r, &e, 0, &r1val)
|| e != range_op) {
error_setg(errp, "Invalid number to the left of %.*s",
(int)(r2 - range_op), range_op);
goto out;
}
- if (qemu_strtoull(r2, NULL, 0, &r2val)) {
+ if (qemu_strtou64(r2, NULL, 0, &r2val)) {
error_setg(errp, "Invalid number to the right of %.*s",
(int)(r2 - range_op), range_op);
goto out;
--
2.7.4
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [Qemu-devel] [PULL 07/24] util/cutils: Clean up variable names around qemu_strtol()
2017-02-23 19:53 [Qemu-devel] [PULL 00/24] option cutils: Fix and clean up number conversions Markus Armbruster
` (5 preceding siblings ...)
2017-02-23 19:53 ` [Qemu-devel] [PULL 06/24] util/cutils: Rename qemu_strtoll(), qemu_strtoull() Markus Armbruster
@ 2017-02-23 19:53 ` Markus Armbruster
2017-02-23 19:53 ` [Qemu-devel] [PULL 08/24] util/cutils: Clean up control flow around qemu_strtol() a bit Markus Armbruster
` (18 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Markus Armbruster @ 2017-02-23 19:53 UTC (permalink / raw)
To: qemu-devel
Name same things the same, different things differently.
* qemu_strtol()'s parameter @nptr is called @p in
check_strtox_error(). Rename the latter.
* qemu_strtol()'s parameter @endptr is called @next in
check_strtox_error(). Rename the latter.
* qemu_strtol()'s variable @p is called @endptr in
check_strtox_error(). Rename both to @ep.
* qemu_strtol()'s variable @err is *negative* errno,
check_strtox_error()'s parameter @err is *positive*. Rename the
latter to @libc_errno.
Same for qemu_strtoul(), qemu_strtoi64(), qemu_strtou64(), of course.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-Id: <1487708048-2131-8-git-send-email-armbru@redhat.com>
---
util/cutils.c | 42 +++++++++++++++++++++---------------------
1 file changed, 21 insertions(+), 21 deletions(-)
diff --git a/util/cutils.c b/util/cutils.c
index 0dc9b28..0fb0f82 100644
--- a/util/cutils.c
+++ b/util/cutils.c
@@ -260,21 +260,21 @@ int64_t qemu_strtosz(const char *nptr, char **end)
}
/**
- * Helper function for qemu_strto*l() functions.
+ * Helper function for error checking after strtol() and the like
*/
-static int check_strtox_error(const char *p, char *endptr, const char **next,
- int err)
+static int check_strtox_error(const char *nptr, char *ep,
+ const char **endptr, int libc_errno)
{
- if (err == 0 && endptr == p) {
- err = EINVAL;
+ if (libc_errno == 0 && ep == nptr) {
+ libc_errno = EINVAL;
}
- if (!next && *endptr) {
+ if (!endptr && *ep) {
return -EINVAL;
}
- if (next) {
- *next = endptr;
+ if (endptr) {
+ *endptr = ep;
}
- return -err;
+ return -libc_errno;
}
/**
@@ -304,7 +304,7 @@ static int check_strtox_error(const char *p, char *endptr, const char **next,
int qemu_strtol(const char *nptr, const char **endptr, int base,
long *result)
{
- char *p;
+ char *ep;
int err = 0;
if (!nptr) {
if (endptr) {
@@ -313,8 +313,8 @@ int qemu_strtol(const char *nptr, const char **endptr, int base,
err = -EINVAL;
} else {
errno = 0;
- *result = strtol(nptr, &p, base);
- err = check_strtox_error(nptr, p, endptr, errno);
+ *result = strtol(nptr, &ep, base);
+ err = check_strtox_error(nptr, ep, endptr, errno);
}
return err;
}
@@ -347,7 +347,7 @@ int qemu_strtol(const char *nptr, const char **endptr, int base,
int qemu_strtoul(const char *nptr, const char **endptr, int base,
unsigned long *result)
{
- char *p;
+ char *ep;
int err = 0;
if (!nptr) {
if (endptr) {
@@ -356,12 +356,12 @@ int qemu_strtoul(const char *nptr, const char **endptr, int base,
err = -EINVAL;
} else {
errno = 0;
- *result = strtoul(nptr, &p, base);
+ *result = strtoul(nptr, &ep, base);
/* Windows returns 1 for negative out-of-range values. */
if (errno == ERANGE) {
*result = -1;
}
- err = check_strtox_error(nptr, p, endptr, errno);
+ err = check_strtox_error(nptr, ep, endptr, errno);
}
return err;
}
@@ -375,7 +375,7 @@ int qemu_strtoul(const char *nptr, const char **endptr, int base,
int qemu_strtoi64(const char *nptr, const char **endptr, int base,
int64_t *result)
{
- char *p;
+ char *ep;
int err = 0;
if (!nptr) {
if (endptr) {
@@ -385,8 +385,8 @@ int qemu_strtoi64(const char *nptr, const char **endptr, int base,
} else {
errno = 0;
/* FIXME This assumes int64_t is long long */
- *result = strtoll(nptr, &p, base);
- err = check_strtox_error(nptr, p, endptr, errno);
+ *result = strtoll(nptr, &ep, base);
+ err = check_strtox_error(nptr, ep, endptr, errno);
}
return err;
}
@@ -399,7 +399,7 @@ int qemu_strtoi64(const char *nptr, const char **endptr, int base,
int qemu_strtou64(const char *nptr, const char **endptr, int base,
uint64_t *result)
{
- char *p;
+ char *ep;
int err = 0;
if (!nptr) {
if (endptr) {
@@ -409,12 +409,12 @@ int qemu_strtou64(const char *nptr, const char **endptr, int base,
} else {
errno = 0;
/* FIXME This assumes uint64_t is unsigned long long */
- *result = strtoull(nptr, &p, base);
+ *result = strtoull(nptr, &ep, base);
/* Windows returns 1 for negative out-of-range values. */
if (errno == ERANGE) {
*result = -1;
}
- err = check_strtox_error(nptr, p, endptr, errno);
+ err = check_strtox_error(nptr, ep, endptr, errno);
}
return err;
}
--
2.7.4
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [Qemu-devel] [PULL 08/24] util/cutils: Clean up control flow around qemu_strtol() a bit
2017-02-23 19:53 [Qemu-devel] [PULL 00/24] option cutils: Fix and clean up number conversions Markus Armbruster
` (6 preceding siblings ...)
2017-02-23 19:53 ` [Qemu-devel] [PULL 07/24] util/cutils: Clean up variable names around qemu_strtol() Markus Armbruster
@ 2017-02-23 19:53 ` Markus Armbruster
2017-02-23 19:53 ` [Qemu-devel] [PULL 09/24] option: Fix to reject invalid and overflowing numbers Markus Armbruster
` (17 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Markus Armbruster @ 2017-02-23 19:53 UTC (permalink / raw)
To: qemu-devel
Reorder check_strtox_error() to make it obvious that we always store
through a non-null @endptr.
Transform
if (some error) {
error case ...
err = value for error case;
} else {
normal case ...
err = value for normal case;
}
return err;
to
if (some error) {
error case ...
return value for error case;
}
normal case ...
return value for normal case;
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-Id: <1487708048-2131-9-git-send-email-armbru@redhat.com>
---
util/cutils.c | 89 ++++++++++++++++++++++++++++++-----------------------------
1 file changed, 45 insertions(+), 44 deletions(-)
diff --git a/util/cutils.c b/util/cutils.c
index 0fb0f82..6397424 100644
--- a/util/cutils.c
+++ b/util/cutils.c
@@ -265,15 +265,20 @@ int64_t qemu_strtosz(const char *nptr, char **end)
static int check_strtox_error(const char *nptr, char *ep,
const char **endptr, int libc_errno)
{
- if (libc_errno == 0 && ep == nptr) {
- libc_errno = EINVAL;
- }
- if (!endptr && *ep) {
- return -EINVAL;
- }
if (endptr) {
*endptr = ep;
}
+
+ /* Turn "no conversion" into an error */
+ if (libc_errno == 0 && ep == nptr) {
+ return -EINVAL;
+ }
+
+ /* Fail when we're expected to consume the string, but didn't */
+ if (!endptr && *ep) {
+ return -EINVAL;
+ }
+
return -libc_errno;
}
@@ -305,18 +310,17 @@ int qemu_strtol(const char *nptr, const char **endptr, int base,
long *result)
{
char *ep;
- int err = 0;
+
if (!nptr) {
if (endptr) {
*endptr = nptr;
}
- err = -EINVAL;
- } else {
- errno = 0;
- *result = strtol(nptr, &ep, base);
- err = check_strtox_error(nptr, ep, endptr, errno);
+ return -EINVAL;
}
- return err;
+
+ errno = 0;
+ *result = strtol(nptr, &ep, base);
+ return check_strtox_error(nptr, ep, endptr, errno);
}
/**
@@ -348,22 +352,21 @@ int qemu_strtoul(const char *nptr, const char **endptr, int base,
unsigned long *result)
{
char *ep;
- int err = 0;
+
if (!nptr) {
if (endptr) {
*endptr = nptr;
}
- err = -EINVAL;
- } else {
- errno = 0;
- *result = strtoul(nptr, &ep, base);
- /* Windows returns 1 for negative out-of-range values. */
- if (errno == ERANGE) {
- *result = -1;
- }
- err = check_strtox_error(nptr, ep, endptr, errno);
+ return -EINVAL;
}
- return err;
+
+ errno = 0;
+ *result = strtoul(nptr, &ep, base);
+ /* Windows returns 1 for negative out-of-range values. */
+ if (errno == ERANGE) {
+ *result = -1;
+ }
+ return check_strtox_error(nptr, ep, endptr, errno);
}
/**
@@ -376,19 +379,18 @@ int qemu_strtoi64(const char *nptr, const char **endptr, int base,
int64_t *result)
{
char *ep;
- int err = 0;
+
if (!nptr) {
if (endptr) {
*endptr = nptr;
}
- err = -EINVAL;
- } else {
- errno = 0;
- /* FIXME This assumes int64_t is long long */
- *result = strtoll(nptr, &ep, base);
- err = check_strtox_error(nptr, ep, endptr, errno);
+ return -EINVAL;
}
- return err;
+
+ errno = 0;
+ /* FIXME This assumes int64_t is long long */
+ *result = strtoll(nptr, &ep, base);
+ return check_strtox_error(nptr, ep, endptr, errno);
}
/**
@@ -400,23 +402,22 @@ int qemu_strtou64(const char *nptr, const char **endptr, int base,
uint64_t *result)
{
char *ep;
- int err = 0;
+
if (!nptr) {
if (endptr) {
*endptr = nptr;
}
- err = -EINVAL;
- } else {
- errno = 0;
- /* FIXME This assumes uint64_t is unsigned long long */
- *result = strtoull(nptr, &ep, base);
- /* Windows returns 1 for negative out-of-range values. */
- if (errno == ERANGE) {
- *result = -1;
- }
- err = check_strtox_error(nptr, ep, endptr, errno);
+ return -EINVAL;
}
- return err;
+
+ errno = 0;
+ /* FIXME This assumes uint64_t is unsigned long long */
+ *result = strtoull(nptr, &ep, base);
+ /* Windows returns 1 for negative out-of-range values. */
+ if (errno == ERANGE) {
+ *result = -1;
+ }
+ return check_strtox_error(nptr, ep, endptr, errno);
}
/**
--
2.7.4
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [Qemu-devel] [PULL 09/24] option: Fix to reject invalid and overflowing numbers
2017-02-23 19:53 [Qemu-devel] [PULL 00/24] option cutils: Fix and clean up number conversions Markus Armbruster
` (7 preceding siblings ...)
2017-02-23 19:53 ` [Qemu-devel] [PULL 08/24] util/cutils: Clean up control flow around qemu_strtol() a bit Markus Armbruster
@ 2017-02-23 19:53 ` Markus Armbruster
2017-02-23 19:53 ` [Qemu-devel] [PULL 10/24] test-cutils: Add missing qemu_strtosz()... endptr checks Markus Armbruster
` (16 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Markus Armbruster @ 2017-02-23 19:53 UTC (permalink / raw)
To: qemu-devel
parse_option_number() fails to check for these errors after
strtoull(). Has always been broken. Fix that.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-Id: <1487708048-2131-10-git-send-email-armbru@redhat.com>
---
tests/test-qemu-opts.c | 19 ++++++++-----------
util/qemu-option.c | 11 ++++++++---
2 files changed, 16 insertions(+), 14 deletions(-)
diff --git a/tests/test-qemu-opts.c b/tests/test-qemu-opts.c
index 310485b..8b92f7b 100644
--- a/tests/test-qemu-opts.c
+++ b/tests/test-qemu-opts.c
@@ -603,17 +603,15 @@ static void test_opts_parse_number(void)
/* Above upper limit */
opts = qemu_opts_parse(&opts_list_01, "number1=18446744073709551616",
- false, &error_abort);
- /* BUG: should reject */
- g_assert_cmpuint(opts_count(opts), ==, 1);
- g_assert_cmpuint(qemu_opt_get_number(opts, "number1", 1), ==, UINT64_MAX);
+ false, &err);
+ error_free_or_abort(&err);
+ g_assert(!opts);
/* Below lower limit */
opts = qemu_opts_parse(&opts_list_01, "number1=-18446744073709551616",
- false, &error_abort);
- /* BUG: should reject */
- g_assert_cmpuint(opts_count(opts), ==, 1);
- g_assert_cmpuint(qemu_opt_get_number(opts, "number1", 1), ==, UINT64_MAX);
+ false, &err);
+ error_free_or_abort(&err);
+ g_assert(!opts);
/* Hex and octal */
opts = qemu_opts_parse(&opts_list_01, "number1=0x2a,number2=052",
@@ -624,9 +622,8 @@ static void test_opts_parse_number(void)
/* Invalid */
opts = qemu_opts_parse(&opts_list_01, "number1=", false, &err);
- /* BUG: should reject */
- g_assert_cmpuint(opts_count(opts), ==, 1);
- g_assert_cmpuint(qemu_opt_get_number(opts, "number1", 1), ==, 0);
+ error_free_or_abort(&err);
+ g_assert(!opts);
opts = qemu_opts_parse(&opts_list_01, "number1=eins", false, &err);
error_free_or_abort(&err);
g_assert(!opts);
diff --git a/util/qemu-option.c b/util/qemu-option.c
index 9708668..273d00d 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -141,11 +141,16 @@ static void parse_option_bool(const char *name, const char *value, bool *ret,
static void parse_option_number(const char *name, const char *value,
uint64_t *ret, Error **errp)
{
- char *postfix;
uint64_t number;
+ int err;
- number = strtoull(value, &postfix, 0);
- if (*postfix != '\0') {
+ err = qemu_strtou64(value, NULL, 0, &number);
+ 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 number");
return;
}
--
2.7.4
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [Qemu-devel] [PULL 10/24] test-cutils: Add missing qemu_strtosz()... endptr checks
2017-02-23 19:53 [Qemu-devel] [PULL 00/24] option cutils: Fix and clean up number conversions Markus Armbruster
` (8 preceding siblings ...)
2017-02-23 19:53 ` [Qemu-devel] [PULL 09/24] option: Fix to reject invalid and overflowing numbers Markus Armbruster
@ 2017-02-23 19:53 ` Markus Armbruster
2017-02-23 19:53 ` [Qemu-devel] [PULL 11/24] test-cutils: Cover qemu_strtosz() invalid input Markus Armbruster
` (15 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Markus Armbruster @ 2017-02-23 19:53 UTC (permalink / raw)
To: qemu-devel
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-Id: <1487708048-2131-11-git-send-email-armbru@redhat.com>
---
tests/test-cutils.c | 37 ++++++++++++++++++++++++++-----------
1 file changed, 26 insertions(+), 11 deletions(-)
diff --git a/tests/test-cutils.c b/tests/test-cutils.c
index 185b023..a3eb182 100644
--- a/tests/test-cutils.c
+++ b/tests/test-cutils.c
@@ -1393,60 +1393,75 @@ static void test_qemu_strtosz_units(void)
const char *t = "1T";
const char *p = "1P";
const char *e = "1E";
+ char *endptr = NULL;
int64_t res;
/* default is M */
- res = qemu_strtosz(none, NULL);
+ res = qemu_strtosz(none, &endptr);
g_assert_cmpint(res, ==, M_BYTE);
+ g_assert(endptr == none + 1);
- res = qemu_strtosz(b, NULL);
+ res = qemu_strtosz(b, &endptr);
g_assert_cmpint(res, ==, 1);
+ g_assert(endptr == b + 2);
- res = qemu_strtosz(k, NULL);
+ res = qemu_strtosz(k, &endptr);
g_assert_cmpint(res, ==, K_BYTE);
+ g_assert(endptr == k + 2);
- res = qemu_strtosz(m, NULL);
+ res = qemu_strtosz(m, &endptr);
g_assert_cmpint(res, ==, M_BYTE);
+ g_assert(endptr == m + 2);
- res = qemu_strtosz(g, NULL);
+ res = qemu_strtosz(g, &endptr);
g_assert_cmpint(res, ==, G_BYTE);
+ g_assert(endptr == g + 2);
- res = qemu_strtosz(t, NULL);
+ res = qemu_strtosz(t, &endptr);
g_assert_cmpint(res, ==, T_BYTE);
+ g_assert(endptr == t + 2);
- res = qemu_strtosz(p, NULL);
+ res = qemu_strtosz(p, &endptr);
g_assert_cmpint(res, ==, P_BYTE);
+ g_assert(endptr == p + 2);
- res = qemu_strtosz(e, NULL);
+ res = qemu_strtosz(e, &endptr);
g_assert_cmpint(res, ==, E_BYTE);
+ g_assert(endptr == e + 2);
}
static void test_qemu_strtosz_float(void)
{
const char *str = "12.345M";
+ char *endptr = NULL;
int64_t res;
- res = qemu_strtosz(str, NULL);
+ res = qemu_strtosz(str, &endptr);
g_assert_cmpint(res, ==, 12.345 * M_BYTE);
+ g_assert(endptr == str + 7);
}
static void test_qemu_strtosz_erange(void)
{
const char *str = "10E";
+ char *endptr = NULL;
int64_t res;
- res = qemu_strtosz(str, NULL);
+ res = qemu_strtosz(str, &endptr);
g_assert_cmpint(res, ==, -ERANGE);
+ g_assert(endptr == str + 3);
}
static void test_qemu_strtosz_suffix_unit(void)
{
const char *str = "12345";
+ char *endptr = NULL;
int64_t res;
- res = qemu_strtosz_suffix_unit(str, NULL,
+ res = qemu_strtosz_suffix_unit(str, &endptr,
QEMU_STRTOSZ_DEFSUFFIX_KB, 1000);
g_assert_cmpint(res, ==, 12345000);
+ g_assert(endptr == str + 5);
}
int main(int argc, char **argv)
--
2.7.4
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [Qemu-devel] [PULL 11/24] test-cutils: Cover qemu_strtosz() invalid input
2017-02-23 19:53 [Qemu-devel] [PULL 00/24] option cutils: Fix and clean up number conversions Markus Armbruster
` (9 preceding siblings ...)
2017-02-23 19:53 ` [Qemu-devel] [PULL 10/24] test-cutils: Add missing qemu_strtosz()... endptr checks Markus Armbruster
@ 2017-02-23 19:53 ` Markus Armbruster
2017-02-23 19:53 ` [Qemu-devel] [PULL 12/24] test-cutils: Cover qemu_strtosz() with trailing crap Markus Armbruster
` (14 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Markus Armbruster @ 2017-02-23 19:53 UTC (permalink / raw)
To: qemu-devel
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-Id: <1487708048-2131-12-git-send-email-armbru@redhat.com>
---
tests/test-cutils.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/tests/test-cutils.c b/tests/test-cutils.c
index a3eb182..dc8cd8d 100644
--- a/tests/test-cutils.c
+++ b/tests/test-cutils.c
@@ -1441,6 +1441,28 @@ static void test_qemu_strtosz_float(void)
g_assert(endptr == str + 7);
}
+static void test_qemu_strtosz_invalid(void)
+{
+ const char *str;
+ char *endptr = NULL;
+ int64_t res;
+
+ str = "";
+ res = qemu_strtosz(str, &endptr);
+ g_assert_cmpint(res, ==, -EINVAL);
+ g_assert(endptr == str);
+
+ str = " \t ";
+ res = qemu_strtosz(str, &endptr);
+ g_assert_cmpint(res, ==, -EINVAL);
+ g_assert(endptr == str);
+
+ str = "crap";
+ res = qemu_strtosz(str, &endptr);
+ g_assert_cmpint(res, ==, -EINVAL);
+ g_assert(endptr == str);
+}
+
static void test_qemu_strtosz_erange(void)
{
const char *str = "10E";
@@ -1652,6 +1674,8 @@ int main(int argc, char **argv)
test_qemu_strtosz_units);
g_test_add_func("/cutils/strtosz/float",
test_qemu_strtosz_float);
+ g_test_add_func("/cutils/strtosz/invalid",
+ test_qemu_strtosz_invalid);
g_test_add_func("/cutils/strtosz/erange",
test_qemu_strtosz_erange);
g_test_add_func("/cutils/strtosz/suffix-unit",
--
2.7.4
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [Qemu-devel] [PULL 12/24] test-cutils: Cover qemu_strtosz() with trailing crap
2017-02-23 19:53 [Qemu-devel] [PULL 00/24] option cutils: Fix and clean up number conversions Markus Armbruster
` (10 preceding siblings ...)
2017-02-23 19:53 ` [Qemu-devel] [PULL 11/24] test-cutils: Cover qemu_strtosz() invalid input Markus Armbruster
@ 2017-02-23 19:53 ` Markus Armbruster
2017-02-23 19:53 ` [Qemu-devel] [PULL 13/24] test-cutils: Cover qemu_strtosz() around range limits Markus Armbruster
` (13 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Markus Armbruster @ 2017-02-23 19:53 UTC (permalink / raw)
To: qemu-devel
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-Id: <1487708048-2131-13-git-send-email-armbru@redhat.com>
---
tests/test-cutils.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/tests/test-cutils.c b/tests/test-cutils.c
index dc8cd8d..1773f15 100644
--- a/tests/test-cutils.c
+++ b/tests/test-cutils.c
@@ -1463,6 +1463,23 @@ static void test_qemu_strtosz_invalid(void)
g_assert(endptr == str);
}
+static void test_qemu_strtosz_trailing(void)
+{
+ const char *str;
+ char *endptr = NULL;
+ int64_t res;
+
+ str = "123xxx";
+ res = qemu_strtosz(str, &endptr);
+ g_assert_cmpint(res, ==, 123 * M_BYTE);
+ g_assert(endptr == str + 3);
+
+ str = "1kiB";
+ res = qemu_strtosz(str, &endptr);
+ g_assert_cmpint(res, ==, 1024);
+ g_assert(endptr == str + 2);
+}
+
static void test_qemu_strtosz_erange(void)
{
const char *str = "10E";
@@ -1676,6 +1693,8 @@ int main(int argc, char **argv)
test_qemu_strtosz_float);
g_test_add_func("/cutils/strtosz/invalid",
test_qemu_strtosz_invalid);
+ g_test_add_func("/cutils/strtosz/trailing",
+ test_qemu_strtosz_trailing);
g_test_add_func("/cutils/strtosz/erange",
test_qemu_strtosz_erange);
g_test_add_func("/cutils/strtosz/suffix-unit",
--
2.7.4
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [Qemu-devel] [PULL 13/24] test-cutils: Cover qemu_strtosz() around range limits
2017-02-23 19:53 [Qemu-devel] [PULL 00/24] option cutils: Fix and clean up number conversions Markus Armbruster
` (11 preceding siblings ...)
2017-02-23 19:53 ` [Qemu-devel] [PULL 12/24] test-cutils: Cover qemu_strtosz() with trailing crap Markus Armbruster
@ 2017-02-23 19:53 ` Markus Armbruster
2017-02-23 19:53 ` [Qemu-devel] [PULL 14/24] util/cutils: New qemu_strtosz_metric() Markus Armbruster
` (12 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Markus Armbruster @ 2017-02-23 19:53 UTC (permalink / raw)
To: qemu-devel
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-Id: <1487708048-2131-14-git-send-email-armbru@redhat.com>
---
tests/test-cutils.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 59 insertions(+), 2 deletions(-)
diff --git a/tests/test-cutils.c b/tests/test-cutils.c
index 1773f15..df6c330 100644
--- a/tests/test-cutils.c
+++ b/tests/test-cutils.c
@@ -1371,16 +1371,52 @@ static void test_qemu_strtou64_full_max(void)
static void test_qemu_strtosz_simple(void)
{
- const char *str = "12345M";
+ const char *str;
char *endptr = NULL;
int64_t res;
+ str = "0";
+ res = qemu_strtosz(str, &endptr);
+ g_assert_cmpint(res, ==, 0);
+ g_assert(endptr == str + 1);
+
+ str = "12345M";
res = qemu_strtosz(str, &endptr);
g_assert_cmpint(res, ==, 12345 * M_BYTE);
g_assert(endptr == str + 6);
res = qemu_strtosz(str, NULL);
g_assert_cmpint(res, ==, 12345 * M_BYTE);
+
+ /* Note: precision is 53 bits since we're parsing with strtod() */
+
+ str = "9007199254740991"; /* 2^53-1 */
+ res = qemu_strtosz_suffix(str, &endptr, QEMU_STRTOSZ_DEFSUFFIX_B);
+ g_assert_cmpint(res, ==, 0x1fffffffffffff);
+ g_assert(endptr == str + 16);
+
+ str = "9007199254740992"; /* 2^53 */
+ res = qemu_strtosz_suffix(str, &endptr, QEMU_STRTOSZ_DEFSUFFIX_B);
+ g_assert_cmpint(res, ==, 0x20000000000000);
+ g_assert(endptr == str + 16);
+
+ str = "9007199254740993"; /* 2^53+1 */
+ res = qemu_strtosz_suffix(str, &endptr, QEMU_STRTOSZ_DEFSUFFIX_B);
+ g_assert_cmpint(res, ==, 0x20000000000000); /* rounded to 53 bits */
+ g_assert(endptr == str + 16);
+
+ str = "9223372036854774784"; /* 0x7ffffffffffffc00 (53 msbs set) */
+ res = qemu_strtosz_suffix(str, &endptr, QEMU_STRTOSZ_DEFSUFFIX_B);
+ g_assert_cmpint(res, ==, 0x7ffffffffffffc00);
+ g_assert(endptr == str + 19);
+
+ str = "9223372036854775295"; /* 0x7ffffffffffffdff */
+ res = qemu_strtosz_suffix(str, &endptr, QEMU_STRTOSZ_DEFSUFFIX_B);
+ g_assert_cmpint(res, ==, 0x7ffffffffffffc00); /* rounded to 53 bits */
+ g_assert(endptr == str + 19);
+
+ /* 0x7ffffffffffffe00..0x7fffffffffffffff get rounded to
+ * 0x8000000000000000, thus -ERANGE; see test_qemu_strtosz_erange() */
}
static void test_qemu_strtosz_units(void)
@@ -1482,10 +1518,31 @@ static void test_qemu_strtosz_trailing(void)
static void test_qemu_strtosz_erange(void)
{
- const char *str = "10E";
+ const char *str;
char *endptr = NULL;
int64_t res;
+ str = "-1";
+ res = qemu_strtosz(str, &endptr);
+ g_assert_cmpint(res, ==, -ERANGE);
+ g_assert(endptr == str + 2);
+
+ str = "9223372036854775296"; /* 0x7ffffffffffffe00 */
+ res = qemu_strtosz_suffix(str, &endptr, QEMU_STRTOSZ_DEFSUFFIX_B);
+ g_assert_cmpint(res, ==, -ERANGE);
+ g_assert(endptr == str + 19);
+
+ str = "9223372036854775807"; /* 2^63-1 */
+ res = qemu_strtosz_suffix(str, &endptr, QEMU_STRTOSZ_DEFSUFFIX_B);
+ g_assert_cmpint(res, ==, -ERANGE);
+ g_assert(endptr == str + 19);
+
+ str = "9223372036854775808"; /* 2^63 */
+ res = qemu_strtosz_suffix(str, &endptr, QEMU_STRTOSZ_DEFSUFFIX_B);
+ g_assert_cmpint(res, ==, -ERANGE);
+ g_assert(endptr == str + 19);
+
+ str = "10E";
res = qemu_strtosz(str, &endptr);
g_assert_cmpint(res, ==, -ERANGE);
g_assert(endptr == str + 3);
--
2.7.4
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [Qemu-devel] [PULL 14/24] util/cutils: New qemu_strtosz_metric()
2017-02-23 19:53 [Qemu-devel] [PULL 00/24] option cutils: Fix and clean up number conversions Markus Armbruster
` (12 preceding siblings ...)
2017-02-23 19:53 ` [Qemu-devel] [PULL 13/24] test-cutils: Cover qemu_strtosz() around range limits Markus Armbruster
@ 2017-02-23 19:53 ` Markus Armbruster
2017-02-23 19:53 ` [Qemu-devel] [PULL 15/24] util/cutils: Rename qemu_strtosz() to qemu_strtosz_MiB() Markus Armbruster
` (11 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Markus Armbruster @ 2017-02-23 19:53 UTC (permalink / raw)
To: qemu-devel
To parse numbers with metric suffixes, we use
qemu_strtosz_suffix_unit(nptr, &eptr, QEMU_STRTOSZ_DEFSUFFIX_B, 1000)
Capture this in a new function for legibility:
qemu_strtosz_metric(nptr, &eptr)
Replace test_qemu_strtosz_suffix_unit() by test_qemu_strtosz_metric().
Rename qemu_strtosz_suffix_unit() to do_strtosz() and give it internal
linkage.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-Id: <1487708048-2131-15-git-send-email-armbru@redhat.com>
---
include/qemu/cutils.h | 4 ++--
target/i386/cpu.c | 3 +--
tests/test-cutils.c | 13 ++++++-------
util/cutils.c | 11 ++++++++---
4 files changed, 17 insertions(+), 14 deletions(-)
diff --git a/include/qemu/cutils.h b/include/qemu/cutils.h
index f922223..81613d0 100644
--- a/include/qemu/cutils.h
+++ b/include/qemu/cutils.h
@@ -156,8 +156,8 @@ int parse_uint_full(const char *s, unsigned long long *value, int base);
int64_t qemu_strtosz(const char *nptr, char **end);
int64_t qemu_strtosz_suffix(const char *nptr, char **end,
const char default_suffix);
-int64_t qemu_strtosz_suffix_unit(const char *nptr, char **end,
- const char default_suffix, int64_t unit);
+int64_t qemu_strtosz_metric(const char *nptr, char **end);
+
#define K_BYTE (1ULL << 10)
#define M_BYTE (1ULL << 20)
#define G_BYTE (1ULL << 30)
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index fd7add2..685ca36 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -2036,8 +2036,7 @@ static void x86_cpu_parse_featurestr(const char *typename, char *features,
int64_t tsc_freq;
char *err;
- tsc_freq = qemu_strtosz_suffix_unit(val, &err,
- QEMU_STRTOSZ_DEFSUFFIX_B, 1000);
+ tsc_freq = qemu_strtosz_metric(val, &err);
if (tsc_freq < 0 || *err) {
error_setg(errp, "bad numerical value %s", val);
return;
diff --git a/tests/test-cutils.c b/tests/test-cutils.c
index df6c330..e1d4054 100644
--- a/tests/test-cutils.c
+++ b/tests/test-cutils.c
@@ -1548,16 +1548,15 @@ static void test_qemu_strtosz_erange(void)
g_assert(endptr == str + 3);
}
-static void test_qemu_strtosz_suffix_unit(void)
+static void test_qemu_strtosz_metric(void)
{
- const char *str = "12345";
+ const char *str = "12345k";
char *endptr = NULL;
int64_t res;
- res = qemu_strtosz_suffix_unit(str, &endptr,
- QEMU_STRTOSZ_DEFSUFFIX_KB, 1000);
+ res = qemu_strtosz_metric(str, &endptr);
g_assert_cmpint(res, ==, 12345000);
- g_assert(endptr == str + 5);
+ g_assert(endptr == str + 6);
}
int main(int argc, char **argv)
@@ -1754,8 +1753,8 @@ int main(int argc, char **argv)
test_qemu_strtosz_trailing);
g_test_add_func("/cutils/strtosz/erange",
test_qemu_strtosz_erange);
- g_test_add_func("/cutils/strtosz/suffix-unit",
- test_qemu_strtosz_suffix_unit);
+ g_test_add_func("/cutils/strtosz/metric",
+ test_qemu_strtosz_metric);
return g_test_run();
}
diff --git a/util/cutils.c b/util/cutils.c
index 6397424..b46e254 100644
--- a/util/cutils.c
+++ b/util/cutils.c
@@ -205,8 +205,8 @@ static int64_t suffix_mul(char suffix, int64_t unit)
* in *end, if not NULL. Return -ERANGE on overflow, Return -EINVAL on
* other error.
*/
-int64_t qemu_strtosz_suffix_unit(const char *nptr, char **end,
- const char default_suffix, int64_t unit)
+static int64_t do_strtosz(const char *nptr, char **end,
+ const char default_suffix, int64_t unit)
{
int64_t retval = -EINVAL;
char *endptr;
@@ -251,7 +251,7 @@ fail:
int64_t qemu_strtosz_suffix(const char *nptr, char **end,
const char default_suffix)
{
- return qemu_strtosz_suffix_unit(nptr, end, default_suffix, 1024);
+ return do_strtosz(nptr, end, default_suffix, 1024);
}
int64_t qemu_strtosz(const char *nptr, char **end)
@@ -259,6 +259,11 @@ int64_t qemu_strtosz(const char *nptr, char **end)
return qemu_strtosz_suffix(nptr, end, QEMU_STRTOSZ_DEFSUFFIX_MB);
}
+int64_t qemu_strtosz_metric(const char *nptr, char **end)
+{
+ return do_strtosz(nptr, end, QEMU_STRTOSZ_DEFSUFFIX_B, 1000);
+}
+
/**
* Helper function for error checking after strtol() and the like
*/
--
2.7.4
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [Qemu-devel] [PULL 15/24] util/cutils: Rename qemu_strtosz() to qemu_strtosz_MiB()
2017-02-23 19:53 [Qemu-devel] [PULL 00/24] option cutils: Fix and clean up number conversions Markus Armbruster
` (13 preceding siblings ...)
2017-02-23 19:53 ` [Qemu-devel] [PULL 14/24] util/cutils: New qemu_strtosz_metric() Markus Armbruster
@ 2017-02-23 19:53 ` Markus Armbruster
2017-02-23 19:53 ` [Qemu-devel] [PULL 16/24] util/cutils: New qemu_strtosz() Markus Armbruster
` (10 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Markus Armbruster @ 2017-02-23 19:53 UTC (permalink / raw)
To: qemu-devel
With qemu_strtosz(), no suffix means mebibytes. It's used rarely.
I'm going to add a similar function where no suffix means bytes.
Rename qemu_strtosz() to qemu_strtosz_MiB() to make the name
qemu_strtosz() available for the new function.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-Id: <1487708048-2131-16-git-send-email-armbru@redhat.com>
---
hmp.c | 2 +-
hw/misc/ivshmem.c | 2 +-
include/qemu/cutils.h | 2 +-
monitor.c | 2 +-
tests/test-cutils.c | 38 +++++++++++++++++++-------------------
util/cutils.c | 2 +-
6 files changed, 24 insertions(+), 24 deletions(-)
diff --git a/hmp.c b/hmp.c
index aba728f..72a5256 100644
--- a/hmp.c
+++ b/hmp.c
@@ -1385,7 +1385,7 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict)
break;
case MIGRATION_PARAMETER_MAX_BANDWIDTH:
p.has_max_bandwidth = true;
- valuebw = qemu_strtosz(valuestr, &endp);
+ valuebw = qemu_strtosz_MiB(valuestr, &endp);
if (valuebw < 0 || (size_t)valuebw != valuebw
|| *endp != '\0') {
error_setg(&err, "Invalid size %s", valuestr);
diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c
index bf57e63..b3d9ed9 100644
--- a/hw/misc/ivshmem.c
+++ b/hw/misc/ivshmem.c
@@ -1268,7 +1268,7 @@ static void ivshmem_realize(PCIDevice *dev, Error **errp)
s->legacy_size = 4 << 20; /* 4 MB default */
} else {
char *end;
- int64_t size = qemu_strtosz(s->sizearg, &end);
+ int64_t size = qemu_strtosz_MiB(s->sizearg, &end);
if (size < 0 || (size_t)size != size || *end != '\0'
|| !is_power_of_2(size)) {
error_setg(errp, "Invalid size %s", s->sizearg);
diff --git a/include/qemu/cutils.h b/include/qemu/cutils.h
index 81613d0..a08b1b0 100644
--- a/include/qemu/cutils.h
+++ b/include/qemu/cutils.h
@@ -153,9 +153,9 @@ int parse_uint_full(const char *s, unsigned long long *value, int base);
#define QEMU_STRTOSZ_DEFSUFFIX_MB 'M'
#define QEMU_STRTOSZ_DEFSUFFIX_KB 'K'
#define QEMU_STRTOSZ_DEFSUFFIX_B 'B'
-int64_t qemu_strtosz(const char *nptr, char **end);
int64_t qemu_strtosz_suffix(const char *nptr, char **end,
const char default_suffix);
+int64_t qemu_strtosz_MiB(const char *nptr, char **end);
int64_t qemu_strtosz_metric(const char *nptr, char **end);
#define K_BYTE (1ULL << 10)
diff --git a/monitor.c b/monitor.c
index 5953fc9..c2c1e42 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2811,7 +2811,7 @@ static QDict *monitor_parse_arguments(Monitor *mon,
break;
}
}
- val = qemu_strtosz(p, &end);
+ val = qemu_strtosz_MiB(p, &end);
if (val < 0) {
monitor_printf(mon, "invalid size\n");
goto fail;
diff --git a/tests/test-cutils.c b/tests/test-cutils.c
index e1d4054..9bbfb8f 100644
--- a/tests/test-cutils.c
+++ b/tests/test-cutils.c
@@ -1376,16 +1376,16 @@ static void test_qemu_strtosz_simple(void)
int64_t res;
str = "0";
- res = qemu_strtosz(str, &endptr);
+ res = qemu_strtosz_MiB(str, &endptr);
g_assert_cmpint(res, ==, 0);
g_assert(endptr == str + 1);
str = "12345M";
- res = qemu_strtosz(str, &endptr);
+ res = qemu_strtosz_MiB(str, &endptr);
g_assert_cmpint(res, ==, 12345 * M_BYTE);
g_assert(endptr == str + 6);
- res = qemu_strtosz(str, NULL);
+ res = qemu_strtosz_MiB(str, NULL);
g_assert_cmpint(res, ==, 12345 * M_BYTE);
/* Note: precision is 53 bits since we're parsing with strtod() */
@@ -1433,35 +1433,35 @@ static void test_qemu_strtosz_units(void)
int64_t res;
/* default is M */
- res = qemu_strtosz(none, &endptr);
+ res = qemu_strtosz_MiB(none, &endptr);
g_assert_cmpint(res, ==, M_BYTE);
g_assert(endptr == none + 1);
- res = qemu_strtosz(b, &endptr);
+ res = qemu_strtosz_MiB(b, &endptr);
g_assert_cmpint(res, ==, 1);
g_assert(endptr == b + 2);
- res = qemu_strtosz(k, &endptr);
+ res = qemu_strtosz_MiB(k, &endptr);
g_assert_cmpint(res, ==, K_BYTE);
g_assert(endptr == k + 2);
- res = qemu_strtosz(m, &endptr);
+ res = qemu_strtosz_MiB(m, &endptr);
g_assert_cmpint(res, ==, M_BYTE);
g_assert(endptr == m + 2);
- res = qemu_strtosz(g, &endptr);
+ res = qemu_strtosz_MiB(g, &endptr);
g_assert_cmpint(res, ==, G_BYTE);
g_assert(endptr == g + 2);
- res = qemu_strtosz(t, &endptr);
+ res = qemu_strtosz_MiB(t, &endptr);
g_assert_cmpint(res, ==, T_BYTE);
g_assert(endptr == t + 2);
- res = qemu_strtosz(p, &endptr);
+ res = qemu_strtosz_MiB(p, &endptr);
g_assert_cmpint(res, ==, P_BYTE);
g_assert(endptr == p + 2);
- res = qemu_strtosz(e, &endptr);
+ res = qemu_strtosz_MiB(e, &endptr);
g_assert_cmpint(res, ==, E_BYTE);
g_assert(endptr == e + 2);
}
@@ -1472,7 +1472,7 @@ static void test_qemu_strtosz_float(void)
char *endptr = NULL;
int64_t res;
- res = qemu_strtosz(str, &endptr);
+ res = qemu_strtosz_MiB(str, &endptr);
g_assert_cmpint(res, ==, 12.345 * M_BYTE);
g_assert(endptr == str + 7);
}
@@ -1484,17 +1484,17 @@ static void test_qemu_strtosz_invalid(void)
int64_t res;
str = "";
- res = qemu_strtosz(str, &endptr);
+ res = qemu_strtosz_MiB(str, &endptr);
g_assert_cmpint(res, ==, -EINVAL);
g_assert(endptr == str);
str = " \t ";
- res = qemu_strtosz(str, &endptr);
+ res = qemu_strtosz_MiB(str, &endptr);
g_assert_cmpint(res, ==, -EINVAL);
g_assert(endptr == str);
str = "crap";
- res = qemu_strtosz(str, &endptr);
+ res = qemu_strtosz_MiB(str, &endptr);
g_assert_cmpint(res, ==, -EINVAL);
g_assert(endptr == str);
}
@@ -1506,12 +1506,12 @@ static void test_qemu_strtosz_trailing(void)
int64_t res;
str = "123xxx";
- res = qemu_strtosz(str, &endptr);
+ res = qemu_strtosz_MiB(str, &endptr);
g_assert_cmpint(res, ==, 123 * M_BYTE);
g_assert(endptr == str + 3);
str = "1kiB";
- res = qemu_strtosz(str, &endptr);
+ res = qemu_strtosz_MiB(str, &endptr);
g_assert_cmpint(res, ==, 1024);
g_assert(endptr == str + 2);
}
@@ -1523,7 +1523,7 @@ static void test_qemu_strtosz_erange(void)
int64_t res;
str = "-1";
- res = qemu_strtosz(str, &endptr);
+ res = qemu_strtosz_MiB(str, &endptr);
g_assert_cmpint(res, ==, -ERANGE);
g_assert(endptr == str + 2);
@@ -1543,7 +1543,7 @@ static void test_qemu_strtosz_erange(void)
g_assert(endptr == str + 19);
str = "10E";
- res = qemu_strtosz(str, &endptr);
+ res = qemu_strtosz_MiB(str, &endptr);
g_assert_cmpint(res, ==, -ERANGE);
g_assert(endptr == str + 3);
}
diff --git a/util/cutils.c b/util/cutils.c
index b46e254..9693add 100644
--- a/util/cutils.c
+++ b/util/cutils.c
@@ -254,7 +254,7 @@ int64_t qemu_strtosz_suffix(const char *nptr, char **end,
return do_strtosz(nptr, end, default_suffix, 1024);
}
-int64_t qemu_strtosz(const char *nptr, char **end)
+int64_t qemu_strtosz_MiB(const char *nptr, char **end)
{
return qemu_strtosz_suffix(nptr, end, QEMU_STRTOSZ_DEFSUFFIX_MB);
}
--
2.7.4
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [Qemu-devel] [PULL 16/24] util/cutils: New qemu_strtosz()
2017-02-23 19:53 [Qemu-devel] [PULL 00/24] option cutils: Fix and clean up number conversions Markus Armbruster
` (14 preceding siblings ...)
2017-02-23 19:53 ` [Qemu-devel] [PULL 15/24] util/cutils: Rename qemu_strtosz() to qemu_strtosz_MiB() Markus Armbruster
@ 2017-02-23 19:53 ` Markus Armbruster
2017-02-23 19:53 ` [Qemu-devel] [PULL 17/24] util/cutils: Drop QEMU_STRTOSZ_DEFSUFFIX_* macros Markus Armbruster
` (9 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Markus Armbruster @ 2017-02-23 19:53 UTC (permalink / raw)
To: qemu-devel
Most callers of qemu_strtosz_suffix() pass QEMU_STRTOSZ_DEFSUFFIX_B.
Capture the pattern in new qemu_strtosz().
Inline qemu_strtosz_suffix() into its only remaining caller.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-Id: <1487708048-2131-17-git-send-email-armbru@redhat.com>
---
include/qemu/cutils.h | 17 +----------------
qapi/opts-visitor.c | 3 +--
qemu-img.c | 18 ++++++++----------
qemu-io-cmds.c | 2 +-
tests/test-cutils.c | 16 ++++++++--------
util/cutils.c | 15 +++++++++++----
6 files changed, 30 insertions(+), 41 deletions(-)
diff --git a/include/qemu/cutils.h b/include/qemu/cutils.h
index a08b1b0..3fdbb6b 100644
--- a/include/qemu/cutils.h
+++ b/include/qemu/cutils.h
@@ -139,22 +139,7 @@ int parse_uint(const char *s, unsigned long long *value, char **endptr,
int base);
int parse_uint_full(const char *s, unsigned long long *value, int base);
-/*
- * qemu_strtosz() suffixes used to specify the default treatment of an
- * argument passed to qemu_strtosz() without an explicit suffix.
- * These should be defined using upper case characters in the range
- * A-Z, as qemu_strtosz() will use qemu_toupper() on the given argument
- * prior to comparison.
- */
-#define QEMU_STRTOSZ_DEFSUFFIX_EB 'E'
-#define QEMU_STRTOSZ_DEFSUFFIX_PB 'P'
-#define QEMU_STRTOSZ_DEFSUFFIX_TB 'T'
-#define QEMU_STRTOSZ_DEFSUFFIX_GB 'G'
-#define QEMU_STRTOSZ_DEFSUFFIX_MB 'M'
-#define QEMU_STRTOSZ_DEFSUFFIX_KB 'K'
-#define QEMU_STRTOSZ_DEFSUFFIX_B 'B'
-int64_t qemu_strtosz_suffix(const char *nptr, char **end,
- const char default_suffix);
+int64_t qemu_strtosz(const char *nptr, char **end);
int64_t qemu_strtosz_MiB(const char *nptr, char **end);
int64_t qemu_strtosz_metric(const char *nptr, char **end);
diff --git a/qapi/opts-visitor.c b/qapi/opts-visitor.c
index 1048bbc..360d337 100644
--- a/qapi/opts-visitor.c
+++ b/qapi/opts-visitor.c
@@ -489,8 +489,7 @@ opts_type_size(Visitor *v, const char *name, uint64_t *obj, Error **errp)
return;
}
- val = qemu_strtosz_suffix(opt->str ? opt->str : "", &endptr,
- QEMU_STRTOSZ_DEFSUFFIX_B);
+ val = qemu_strtosz(opt->str ? opt->str : "", &endptr);
if (val < 0 || *endptr) {
error_setg(errp, QERR_INVALID_PARAMETER_VALUE, opt->name,
"a size value representible as a non-negative int64");
diff --git a/qemu-img.c b/qemu-img.c
index cff22e3..f1c641c 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -462,8 +462,7 @@ static int img_create(int argc, char **argv)
if (optind < argc) {
int64_t sval;
char *end;
- sval = qemu_strtosz_suffix(argv[optind++], &end,
- QEMU_STRTOSZ_DEFSUFFIX_B);
+ sval = qemu_strtosz(argv[optind++], &end);
if (sval < 0 || *end) {
if (sval == -ERANGE) {
error_report("Image size must be less than 8 EiB!");
@@ -1865,7 +1864,7 @@ static int img_convert(int argc, char **argv)
{
int64_t sval;
char *end;
- sval = qemu_strtosz_suffix(optarg, &end, QEMU_STRTOSZ_DEFSUFFIX_B);
+ sval = qemu_strtosz(optarg, &end);
if (sval < 0 || *end) {
error_report("Invalid minimum zero buffer size for sparse output specified");
ret = -1;
@@ -3653,8 +3652,7 @@ static int img_bench(int argc, char **argv)
{
char *end;
errno = 0;
- offset = qemu_strtosz_suffix(optarg, &end,
- QEMU_STRTOSZ_DEFSUFFIX_B);
+ offset = qemu_strtosz(optarg, &end);
if (offset < 0|| *end) {
error_report("Invalid offset specified");
return 1;
@@ -3670,7 +3668,7 @@ static int img_bench(int argc, char **argv)
int64_t sval;
char *end;
- sval = qemu_strtosz_suffix(optarg, &end, QEMU_STRTOSZ_DEFSUFFIX_B);
+ sval = qemu_strtosz(optarg, &end);
if (sval < 0 || sval > INT_MAX || *end) {
error_report("Invalid buffer size specified");
return 1;
@@ -3684,7 +3682,7 @@ static int img_bench(int argc, char **argv)
int64_t sval;
char *end;
- sval = qemu_strtosz_suffix(optarg, &end, QEMU_STRTOSZ_DEFSUFFIX_B);
+ sval = qemu_strtosz(optarg, &end);
if (sval < 0 || sval > INT_MAX || *end) {
error_report("Invalid step size specified");
return 1;
@@ -3847,7 +3845,7 @@ static int img_dd_bs(const char *arg,
char *end;
int64_t res;
- res = qemu_strtosz_suffix(arg, &end, QEMU_STRTOSZ_DEFSUFFIX_B);
+ res = qemu_strtosz(arg, &end);
if (res <= 0 || res > INT_MAX || *end) {
error_report("invalid number: '%s'", arg);
@@ -3864,7 +3862,7 @@ static int img_dd_count(const char *arg,
{
char *end;
- dd->count = qemu_strtosz_suffix(arg, &end, QEMU_STRTOSZ_DEFSUFFIX_B);
+ dd->count = qemu_strtosz(arg, &end);
if (dd->count < 0 || *end) {
error_report("invalid number: '%s'", arg);
@@ -3898,7 +3896,7 @@ static int img_dd_skip(const char *arg,
{
char *end;
- in->offset = qemu_strtosz_suffix(arg, &end, QEMU_STRTOSZ_DEFSUFFIX_B);
+ in->offset = qemu_strtosz(arg, &end);
if (in->offset < 0 || *end) {
error_report("invalid number: '%s'", arg);
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
index e415b03..0166cfa 100644
--- a/qemu-io-cmds.c
+++ b/qemu-io-cmds.c
@@ -140,7 +140,7 @@ static int64_t cvtnum(const char *s)
char *end;
int64_t ret;
- ret = qemu_strtosz_suffix(s, &end, QEMU_STRTOSZ_DEFSUFFIX_B);
+ ret = qemu_strtosz(s, &end);
if (*end != '\0') {
/* Detritus at the end of the string */
return -EINVAL;
diff --git a/tests/test-cutils.c b/tests/test-cutils.c
index 9bbfb8f..9eae067 100644
--- a/tests/test-cutils.c
+++ b/tests/test-cutils.c
@@ -1391,27 +1391,27 @@ static void test_qemu_strtosz_simple(void)
/* Note: precision is 53 bits since we're parsing with strtod() */
str = "9007199254740991"; /* 2^53-1 */
- res = qemu_strtosz_suffix(str, &endptr, QEMU_STRTOSZ_DEFSUFFIX_B);
+ res = qemu_strtosz(str, &endptr);
g_assert_cmpint(res, ==, 0x1fffffffffffff);
g_assert(endptr == str + 16);
str = "9007199254740992"; /* 2^53 */
- res = qemu_strtosz_suffix(str, &endptr, QEMU_STRTOSZ_DEFSUFFIX_B);
+ res = qemu_strtosz(str, &endptr);
g_assert_cmpint(res, ==, 0x20000000000000);
g_assert(endptr == str + 16);
str = "9007199254740993"; /* 2^53+1 */
- res = qemu_strtosz_suffix(str, &endptr, QEMU_STRTOSZ_DEFSUFFIX_B);
+ res = qemu_strtosz(str, &endptr);
g_assert_cmpint(res, ==, 0x20000000000000); /* rounded to 53 bits */
g_assert(endptr == str + 16);
str = "9223372036854774784"; /* 0x7ffffffffffffc00 (53 msbs set) */
- res = qemu_strtosz_suffix(str, &endptr, QEMU_STRTOSZ_DEFSUFFIX_B);
+ res = qemu_strtosz(str, &endptr);
g_assert_cmpint(res, ==, 0x7ffffffffffffc00);
g_assert(endptr == str + 19);
str = "9223372036854775295"; /* 0x7ffffffffffffdff */
- res = qemu_strtosz_suffix(str, &endptr, QEMU_STRTOSZ_DEFSUFFIX_B);
+ res = qemu_strtosz(str, &endptr);
g_assert_cmpint(res, ==, 0x7ffffffffffffc00); /* rounded to 53 bits */
g_assert(endptr == str + 19);
@@ -1528,17 +1528,17 @@ static void test_qemu_strtosz_erange(void)
g_assert(endptr == str + 2);
str = "9223372036854775296"; /* 0x7ffffffffffffe00 */
- res = qemu_strtosz_suffix(str, &endptr, QEMU_STRTOSZ_DEFSUFFIX_B);
+ res = qemu_strtosz(str, &endptr);
g_assert_cmpint(res, ==, -ERANGE);
g_assert(endptr == str + 19);
str = "9223372036854775807"; /* 2^63-1 */
- res = qemu_strtosz_suffix(str, &endptr, QEMU_STRTOSZ_DEFSUFFIX_B);
+ res = qemu_strtosz(str, &endptr);
g_assert_cmpint(res, ==, -ERANGE);
g_assert(endptr == str + 19);
str = "9223372036854775808"; /* 2^63 */
- res = qemu_strtosz_suffix(str, &endptr, QEMU_STRTOSZ_DEFSUFFIX_B);
+ res = qemu_strtosz(str, &endptr);
g_assert_cmpint(res, ==, -ERANGE);
g_assert(endptr == str + 19);
diff --git a/util/cutils.c b/util/cutils.c
index 9693add..97ec130 100644
--- a/util/cutils.c
+++ b/util/cutils.c
@@ -178,6 +178,14 @@ int fcntl_setfl(int fd, int flag)
}
#endif
+#define QEMU_STRTOSZ_DEFSUFFIX_EB 'E'
+#define QEMU_STRTOSZ_DEFSUFFIX_PB 'P'
+#define QEMU_STRTOSZ_DEFSUFFIX_TB 'T'
+#define QEMU_STRTOSZ_DEFSUFFIX_GB 'G'
+#define QEMU_STRTOSZ_DEFSUFFIX_MB 'M'
+#define QEMU_STRTOSZ_DEFSUFFIX_KB 'K'
+#define QEMU_STRTOSZ_DEFSUFFIX_B 'B'
+
static int64_t suffix_mul(char suffix, int64_t unit)
{
switch (qemu_toupper(suffix)) {
@@ -248,15 +256,14 @@ fail:
return retval;
}
-int64_t qemu_strtosz_suffix(const char *nptr, char **end,
- const char default_suffix)
+int64_t qemu_strtosz(const char *nptr, char **end)
{
- return do_strtosz(nptr, end, default_suffix, 1024);
+ return do_strtosz(nptr, end, QEMU_STRTOSZ_DEFSUFFIX_B, 1024);
}
int64_t qemu_strtosz_MiB(const char *nptr, char **end)
{
- return qemu_strtosz_suffix(nptr, end, QEMU_STRTOSZ_DEFSUFFIX_MB);
+ return do_strtosz(nptr, end, QEMU_STRTOSZ_DEFSUFFIX_MB, 1024);
}
int64_t qemu_strtosz_metric(const char *nptr, char **end)
--
2.7.4
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [Qemu-devel] [PULL 17/24] util/cutils: Drop QEMU_STRTOSZ_DEFSUFFIX_* macros
2017-02-23 19:53 [Qemu-devel] [PULL 00/24] option cutils: Fix and clean up number conversions Markus Armbruster
` (15 preceding siblings ...)
2017-02-23 19:53 ` [Qemu-devel] [PULL 16/24] util/cutils: New qemu_strtosz() Markus Armbruster
@ 2017-02-23 19:53 ` Markus Armbruster
2017-02-23 19:53 ` [Qemu-devel] [PULL 18/24] test-cutils: Use qemu_strtosz() more often Markus Armbruster
` (8 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Markus Armbruster @ 2017-02-23 19:53 UTC (permalink / raw)
To: qemu-devel
Writing QEMU_STRTOSZ_DEFSUFFIX_* instead of '*' gains nothing. Get
rid of these eyesores.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-Id: <1487708048-2131-18-git-send-email-armbru@redhat.com>
---
util/cutils.c | 28 ++++++++++------------------
1 file changed, 10 insertions(+), 18 deletions(-)
diff --git a/util/cutils.c b/util/cutils.c
index 97ec130..0ac8019 100644
--- a/util/cutils.c
+++ b/util/cutils.c
@@ -178,30 +178,22 @@ int fcntl_setfl(int fd, int flag)
}
#endif
-#define QEMU_STRTOSZ_DEFSUFFIX_EB 'E'
-#define QEMU_STRTOSZ_DEFSUFFIX_PB 'P'
-#define QEMU_STRTOSZ_DEFSUFFIX_TB 'T'
-#define QEMU_STRTOSZ_DEFSUFFIX_GB 'G'
-#define QEMU_STRTOSZ_DEFSUFFIX_MB 'M'
-#define QEMU_STRTOSZ_DEFSUFFIX_KB 'K'
-#define QEMU_STRTOSZ_DEFSUFFIX_B 'B'
-
static int64_t suffix_mul(char suffix, int64_t unit)
{
switch (qemu_toupper(suffix)) {
- case QEMU_STRTOSZ_DEFSUFFIX_B:
+ case 'B':
return 1;
- case QEMU_STRTOSZ_DEFSUFFIX_KB:
+ case 'K':
return unit;
- case QEMU_STRTOSZ_DEFSUFFIX_MB:
+ case 'M':
return unit * unit;
- case QEMU_STRTOSZ_DEFSUFFIX_GB:
+ case 'G':
return unit * unit * unit;
- case QEMU_STRTOSZ_DEFSUFFIX_TB:
+ case 'T':
return unit * unit * unit * unit;
- case QEMU_STRTOSZ_DEFSUFFIX_PB:
+ case 'P':
return unit * unit * unit * unit * unit;
- case QEMU_STRTOSZ_DEFSUFFIX_EB:
+ case 'E':
return unit * unit * unit * unit * unit * unit;
}
return -1;
@@ -258,17 +250,17 @@ fail:
int64_t qemu_strtosz(const char *nptr, char **end)
{
- return do_strtosz(nptr, end, QEMU_STRTOSZ_DEFSUFFIX_B, 1024);
+ return do_strtosz(nptr, end, 'B', 1024);
}
int64_t qemu_strtosz_MiB(const char *nptr, char **end)
{
- return do_strtosz(nptr, end, QEMU_STRTOSZ_DEFSUFFIX_MB, 1024);
+ return do_strtosz(nptr, end, 'M', 1024);
}
int64_t qemu_strtosz_metric(const char *nptr, char **end)
{
- return do_strtosz(nptr, end, QEMU_STRTOSZ_DEFSUFFIX_B, 1000);
+ return do_strtosz(nptr, end, 'B', 1000);
}
/**
--
2.7.4
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [Qemu-devel] [PULL 18/24] test-cutils: Use qemu_strtosz() more often
2017-02-23 19:53 [Qemu-devel] [PULL 00/24] option cutils: Fix and clean up number conversions Markus Armbruster
` (16 preceding siblings ...)
2017-02-23 19:53 ` [Qemu-devel] [PULL 17/24] util/cutils: Drop QEMU_STRTOSZ_DEFSUFFIX_* macros Markus Armbruster
@ 2017-02-23 19:53 ` Markus Armbruster
2017-02-23 19:53 ` [Qemu-devel] [PULL 19/24] test-cutils: Drop suffix from test_qemu_strtosz_simple() Markus Armbruster
` (7 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Markus Armbruster @ 2017-02-23 19:53 UTC (permalink / raw)
To: qemu-devel
Use qemu_strtosz() instead of qemu_strtosz_MiB() where it doesn't
really make a difference.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-Id: <1487708048-2131-19-git-send-email-armbru@redhat.com>
---
tests/test-cutils.c | 34 +++++++++++++++++-----------------
1 file changed, 17 insertions(+), 17 deletions(-)
diff --git a/tests/test-cutils.c b/tests/test-cutils.c
index 9eae067..d492d1e 100644
--- a/tests/test-cutils.c
+++ b/tests/test-cutils.c
@@ -1376,16 +1376,16 @@ static void test_qemu_strtosz_simple(void)
int64_t res;
str = "0";
- res = qemu_strtosz_MiB(str, &endptr);
+ res = qemu_strtosz(str, &endptr);
g_assert_cmpint(res, ==, 0);
g_assert(endptr == str + 1);
str = "12345M";
- res = qemu_strtosz_MiB(str, &endptr);
+ res = qemu_strtosz(str, &endptr);
g_assert_cmpint(res, ==, 12345 * M_BYTE);
g_assert(endptr == str + 6);
- res = qemu_strtosz_MiB(str, NULL);
+ res = qemu_strtosz(str, NULL);
g_assert_cmpint(res, ==, 12345 * M_BYTE);
/* Note: precision is 53 bits since we're parsing with strtod() */
@@ -1437,31 +1437,31 @@ static void test_qemu_strtosz_units(void)
g_assert_cmpint(res, ==, M_BYTE);
g_assert(endptr == none + 1);
- res = qemu_strtosz_MiB(b, &endptr);
+ res = qemu_strtosz(b, &endptr);
g_assert_cmpint(res, ==, 1);
g_assert(endptr == b + 2);
- res = qemu_strtosz_MiB(k, &endptr);
+ res = qemu_strtosz(k, &endptr);
g_assert_cmpint(res, ==, K_BYTE);
g_assert(endptr == k + 2);
- res = qemu_strtosz_MiB(m, &endptr);
+ res = qemu_strtosz(m, &endptr);
g_assert_cmpint(res, ==, M_BYTE);
g_assert(endptr == m + 2);
- res = qemu_strtosz_MiB(g, &endptr);
+ res = qemu_strtosz(g, &endptr);
g_assert_cmpint(res, ==, G_BYTE);
g_assert(endptr == g + 2);
- res = qemu_strtosz_MiB(t, &endptr);
+ res = qemu_strtosz(t, &endptr);
g_assert_cmpint(res, ==, T_BYTE);
g_assert(endptr == t + 2);
- res = qemu_strtosz_MiB(p, &endptr);
+ res = qemu_strtosz(p, &endptr);
g_assert_cmpint(res, ==, P_BYTE);
g_assert(endptr == p + 2);
- res = qemu_strtosz_MiB(e, &endptr);
+ res = qemu_strtosz(e, &endptr);
g_assert_cmpint(res, ==, E_BYTE);
g_assert(endptr == e + 2);
}
@@ -1472,7 +1472,7 @@ static void test_qemu_strtosz_float(void)
char *endptr = NULL;
int64_t res;
- res = qemu_strtosz_MiB(str, &endptr);
+ res = qemu_strtosz(str, &endptr);
g_assert_cmpint(res, ==, 12.345 * M_BYTE);
g_assert(endptr == str + 7);
}
@@ -1484,17 +1484,17 @@ static void test_qemu_strtosz_invalid(void)
int64_t res;
str = "";
- res = qemu_strtosz_MiB(str, &endptr);
+ res = qemu_strtosz(str, &endptr);
g_assert_cmpint(res, ==, -EINVAL);
g_assert(endptr == str);
str = " \t ";
- res = qemu_strtosz_MiB(str, &endptr);
+ res = qemu_strtosz(str, &endptr);
g_assert_cmpint(res, ==, -EINVAL);
g_assert(endptr == str);
str = "crap";
- res = qemu_strtosz_MiB(str, &endptr);
+ res = qemu_strtosz(str, &endptr);
g_assert_cmpint(res, ==, -EINVAL);
g_assert(endptr == str);
}
@@ -1511,7 +1511,7 @@ static void test_qemu_strtosz_trailing(void)
g_assert(endptr == str + 3);
str = "1kiB";
- res = qemu_strtosz_MiB(str, &endptr);
+ res = qemu_strtosz(str, &endptr);
g_assert_cmpint(res, ==, 1024);
g_assert(endptr == str + 2);
}
@@ -1523,7 +1523,7 @@ static void test_qemu_strtosz_erange(void)
int64_t res;
str = "-1";
- res = qemu_strtosz_MiB(str, &endptr);
+ res = qemu_strtosz(str, &endptr);
g_assert_cmpint(res, ==, -ERANGE);
g_assert(endptr == str + 2);
@@ -1543,7 +1543,7 @@ static void test_qemu_strtosz_erange(void)
g_assert(endptr == str + 19);
str = "10E";
- res = qemu_strtosz_MiB(str, &endptr);
+ res = qemu_strtosz(str, &endptr);
g_assert_cmpint(res, ==, -ERANGE);
g_assert(endptr == str + 3);
}
--
2.7.4
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [Qemu-devel] [PULL 19/24] test-cutils: Drop suffix from test_qemu_strtosz_simple()
2017-02-23 19:53 [Qemu-devel] [PULL 00/24] option cutils: Fix and clean up number conversions Markus Armbruster
` (17 preceding siblings ...)
2017-02-23 19:53 ` [Qemu-devel] [PULL 18/24] test-cutils: Use qemu_strtosz() more often Markus Armbruster
@ 2017-02-23 19:53 ` Markus Armbruster
2017-02-23 19:53 ` [Qemu-devel] [PULL 20/24] qemu-img: Wrap cvtnum() around qemu_strtosz() Markus Armbruster
` (6 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Markus Armbruster @ 2017-02-23 19:53 UTC (permalink / raw)
To: qemu-devel
Leave testing unit suffixes to test_qemu_strtosz_units().
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-Id: <1487708048-2131-20-git-send-email-armbru@redhat.com>
---
tests/test-cutils.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/tests/test-cutils.c b/tests/test-cutils.c
index d492d1e..c4437d9 100644
--- a/tests/test-cutils.c
+++ b/tests/test-cutils.c
@@ -1380,13 +1380,13 @@ static void test_qemu_strtosz_simple(void)
g_assert_cmpint(res, ==, 0);
g_assert(endptr == str + 1);
- str = "12345M";
+ str = "12345";
res = qemu_strtosz(str, &endptr);
- g_assert_cmpint(res, ==, 12345 * M_BYTE);
- g_assert(endptr == str + 6);
+ g_assert_cmpint(res, ==, 12345);
+ g_assert(endptr == str + 5);
res = qemu_strtosz(str, NULL);
- g_assert_cmpint(res, ==, 12345 * M_BYTE);
+ g_assert_cmpint(res, ==, 12345);
/* Note: precision is 53 bits since we're parsing with strtod() */
--
2.7.4
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [Qemu-devel] [PULL 20/24] qemu-img: Wrap cvtnum() around qemu_strtosz()
2017-02-23 19:53 [Qemu-devel] [PULL 00/24] option cutils: Fix and clean up number conversions Markus Armbruster
` (18 preceding siblings ...)
2017-02-23 19:53 ` [Qemu-devel] [PULL 19/24] test-cutils: Drop suffix from test_qemu_strtosz_simple() Markus Armbruster
@ 2017-02-23 19:53 ` Markus Armbruster
2017-02-23 19:53 ` [Qemu-devel] [PULL 21/24] util/cutils: Let qemu_strtosz*() optionally reject trailing crap Markus Armbruster
` (5 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Markus Armbruster @ 2017-02-23 19:53 UTC (permalink / raw)
To: qemu-devel; +Cc: Kevin Wolf, Max Reitz, qemu-block
Cc: Kevin Wolf <kwolf@redhat.com>
Cc: Max Reitz <mreitz@redhat.com>
Cc: qemu-block@nongnu.org
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-Id: <1487708048-2131-21-git-send-email-armbru@redhat.com>
---
qemu-img.c | 58 +++++++++++++++++++++++++++++++---------------------------
1 file changed, 31 insertions(+), 27 deletions(-)
diff --git a/qemu-img.c b/qemu-img.c
index f1c641c..4062917 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -368,6 +368,19 @@ static int add_old_style_options(const char *fmt, QemuOpts *opts,
return 0;
}
+static int64_t cvtnum(const char *s)
+{
+ char *end;
+ int64_t ret;
+
+ ret = qemu_strtosz(s, &end);
+ if (*end != '\0') {
+ /* Detritus at the end of the string */
+ return -EINVAL;
+ }
+ return ret;
+}
+
static int img_create(int argc, char **argv)
{
int c;
@@ -461,9 +474,9 @@ static int img_create(int argc, char **argv)
/* Get image size, if specified */
if (optind < argc) {
int64_t sval;
- char *end;
- sval = qemu_strtosz(argv[optind++], &end);
- if (sval < 0 || *end) {
+
+ sval = cvtnum(argv[optind++]);
+ if (sval < 0) {
if (sval == -ERANGE) {
error_report("Image size must be less than 8 EiB!");
} else {
@@ -1863,9 +1876,9 @@ static int img_convert(int argc, char **argv)
case 'S':
{
int64_t sval;
- char *end;
- sval = qemu_strtosz(optarg, &end);
- if (sval < 0 || *end) {
+
+ sval = cvtnum(optarg);
+ if (sval < 0) {
error_report("Invalid minimum zero buffer size for sparse output specified");
ret = -1;
goto fail_getopt;
@@ -3650,10 +3663,8 @@ static int img_bench(int argc, char **argv)
break;
case 'o':
{
- char *end;
- errno = 0;
- offset = qemu_strtosz(optarg, &end);
- if (offset < 0|| *end) {
+ offset = cvtnum(optarg);
+ if (offset < 0) {
error_report("Invalid offset specified");
return 1;
}
@@ -3666,10 +3677,9 @@ static int img_bench(int argc, char **argv)
case 's':
{
int64_t sval;
- char *end;
- sval = qemu_strtosz(optarg, &end);
- if (sval < 0 || sval > INT_MAX || *end) {
+ sval = cvtnum(optarg);
+ if (sval < 0 || sval > INT_MAX) {
error_report("Invalid buffer size specified");
return 1;
}
@@ -3680,10 +3690,9 @@ static int img_bench(int argc, char **argv)
case 'S':
{
int64_t sval;
- char *end;
- sval = qemu_strtosz(optarg, &end);
- if (sval < 0 || sval > INT_MAX || *end) {
+ sval = cvtnum(optarg);
+ if (sval < 0 || sval > INT_MAX) {
error_report("Invalid step size specified");
return 1;
}
@@ -3842,12 +3851,11 @@ static int img_dd_bs(const char *arg,
struct DdIo *in, struct DdIo *out,
struct DdInfo *dd)
{
- char *end;
int64_t res;
- res = qemu_strtosz(arg, &end);
+ res = cvtnum(arg);
- if (res <= 0 || res > INT_MAX || *end) {
+ if (res <= 0 || res > INT_MAX) {
error_report("invalid number: '%s'", arg);
return 1;
}
@@ -3860,11 +3868,9 @@ static int img_dd_count(const char *arg,
struct DdIo *in, struct DdIo *out,
struct DdInfo *dd)
{
- char *end;
+ dd->count = cvtnum(arg);
- dd->count = qemu_strtosz(arg, &end);
-
- if (dd->count < 0 || *end) {
+ if (dd->count < 0) {
error_report("invalid number: '%s'", arg);
return 1;
}
@@ -3894,11 +3900,9 @@ static int img_dd_skip(const char *arg,
struct DdIo *in, struct DdIo *out,
struct DdInfo *dd)
{
- char *end;
+ in->offset = cvtnum(arg);
- in->offset = qemu_strtosz(arg, &end);
-
- if (in->offset < 0 || *end) {
+ if (in->offset < 0) {
error_report("invalid number: '%s'", arg);
return 1;
}
--
2.7.4
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [Qemu-devel] [PULL 21/24] util/cutils: Let qemu_strtosz*() optionally reject trailing crap
2017-02-23 19:53 [Qemu-devel] [PULL 00/24] option cutils: Fix and clean up number conversions Markus Armbruster
` (19 preceding siblings ...)
2017-02-23 19:53 ` [Qemu-devel] [PULL 20/24] qemu-img: Wrap cvtnum() around qemu_strtosz() Markus Armbruster
@ 2017-02-23 19:53 ` Markus Armbruster
2017-02-23 19:54 ` [Qemu-devel] [PULL 22/24] util/cutils: Return qemu_strtosz*() error and value separately Markus Armbruster
` (4 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Markus Armbruster @ 2017-02-23 19:53 UTC (permalink / raw)
To: qemu-devel
Cc: Dr . David Alan Gilbert, Eduardo Habkost, Kevin Wolf, Max Reitz,
open list:Block layer core
Change the qemu_strtosz() & friends to return -EINVAL when @endptr is
null and the conversion doesn't consume the string completely.
Matches how qemu_strtol() & friends work.
Only test_qemu_strtosz_simple() passes a null @endptr. No functional
change there, because its conversion consumes the string.
Simplify callers that use @endptr only to fail when it doesn't point
to '\0' to pass a null @endptr instead.
Cc: Dr. David Alan Gilbert <dgilbert@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com> (maintainer:X86)
Cc: Kevin Wolf <kwolf@redhat.com> (supporter:Block layer core)
Cc: Max Reitz <mreitz@redhat.com> (supporter:Block layer core)
Cc: qemu-block@nongnu.org (open list:Block layer core)
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Message-Id: <1487708048-2131-22-git-send-email-armbru@redhat.com>
---
hmp.c | 6 ++----
hw/misc/ivshmem.c | 6 ++----
qapi/opts-visitor.c | 5 ++---
qemu-img.c | 7 +------
qemu-io-cmds.c | 7 +------
target/i386/cpu.c | 5 ++---
tests/test-cutils.c | 6 ++++++
util/cutils.c | 14 +++++++++-----
8 files changed, 25 insertions(+), 31 deletions(-)
diff --git a/hmp.c b/hmp.c
index 72a5256..2269e8b 100644
--- a/hmp.c
+++ b/hmp.c
@@ -1346,7 +1346,6 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict)
const char *valuestr = qdict_get_str(qdict, "value");
int64_t valuebw = 0;
long valueint = 0;
- char *endp;
Error *err = NULL;
bool use_int_value = false;
int i;
@@ -1385,9 +1384,8 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict)
break;
case MIGRATION_PARAMETER_MAX_BANDWIDTH:
p.has_max_bandwidth = true;
- valuebw = qemu_strtosz_MiB(valuestr, &endp);
- if (valuebw < 0 || (size_t)valuebw != valuebw
- || *endp != '\0') {
+ valuebw = qemu_strtosz_MiB(valuestr, NULL);
+ if (valuebw < 0 || (size_t)valuebw != valuebw) {
error_setg(&err, "Invalid size %s", valuestr);
goto cleanup;
}
diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c
index b3d9ed9..848bebc 100644
--- a/hw/misc/ivshmem.c
+++ b/hw/misc/ivshmem.c
@@ -1267,10 +1267,8 @@ static void ivshmem_realize(PCIDevice *dev, Error **errp)
if (s->sizearg == NULL) {
s->legacy_size = 4 << 20; /* 4 MB default */
} else {
- char *end;
- int64_t size = qemu_strtosz_MiB(s->sizearg, &end);
- if (size < 0 || (size_t)size != size || *end != '\0'
- || !is_power_of_2(size)) {
+ int64_t size = qemu_strtosz_MiB(s->sizearg, NULL);
+ if (size < 0 || (size_t)size != size || !is_power_of_2(size)) {
error_setg(errp, "Invalid size %s", s->sizearg);
return;
}
diff --git a/qapi/opts-visitor.c b/qapi/opts-visitor.c
index 360d337..911a0ee 100644
--- a/qapi/opts-visitor.c
+++ b/qapi/opts-visitor.c
@@ -482,15 +482,14 @@ opts_type_size(Visitor *v, const char *name, uint64_t *obj, Error **errp)
OptsVisitor *ov = to_ov(v);
const QemuOpt *opt;
int64_t val;
- char *endptr;
opt = lookup_scalar(ov, name, errp);
if (!opt) {
return;
}
- val = qemu_strtosz(opt->str ? opt->str : "", &endptr);
- if (val < 0 || *endptr) {
+ val = qemu_strtosz(opt->str ? opt->str : "", NULL);
+ if (val < 0) {
error_setg(errp, QERR_INVALID_PARAMETER_VALUE, opt->name,
"a size value representible as a non-negative int64");
return;
diff --git a/qemu-img.c b/qemu-img.c
index 4062917..39ef581 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -370,14 +370,9 @@ static int add_old_style_options(const char *fmt, QemuOpts *opts,
static int64_t cvtnum(const char *s)
{
- char *end;
int64_t ret;
- ret = qemu_strtosz(s, &end);
- if (*end != '\0') {
- /* Detritus at the end of the string */
- return -EINVAL;
- }
+ ret = qemu_strtosz(s, NULL);
return ret;
}
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
index 0166cfa..973eb94 100644
--- a/qemu-io-cmds.c
+++ b/qemu-io-cmds.c
@@ -137,14 +137,9 @@ static char **breakline(char *input, int *count)
static int64_t cvtnum(const char *s)
{
- char *end;
int64_t ret;
- ret = qemu_strtosz(s, &end);
- if (*end != '\0') {
- /* Detritus at the end of the string */
- return -EINVAL;
- }
+ ret = qemu_strtosz(s, NULL);
return ret;
}
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 685ca36..58a05ec 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -2034,10 +2034,9 @@ static void x86_cpu_parse_featurestr(const char *typename, char *features,
/* Special case: */
if (!strcmp(name, "tsc-freq")) {
int64_t tsc_freq;
- char *err;
- tsc_freq = qemu_strtosz_metric(val, &err);
- if (tsc_freq < 0 || *err) {
+ tsc_freq = qemu_strtosz_metric(val, NULL);
+ if (tsc_freq < 0) {
error_setg(errp, "bad numerical value %s", val);
return;
}
diff --git a/tests/test-cutils.c b/tests/test-cutils.c
index c4437d9..f2ecb7a 100644
--- a/tests/test-cutils.c
+++ b/tests/test-cutils.c
@@ -1510,10 +1510,16 @@ static void test_qemu_strtosz_trailing(void)
g_assert_cmpint(res, ==, 123 * M_BYTE);
g_assert(endptr == str + 3);
+ res = qemu_strtosz(str, NULL);
+ g_assert_cmpint(res, ==, -EINVAL);
+
str = "1kiB";
res = qemu_strtosz(str, &endptr);
g_assert_cmpint(res, ==, 1024);
g_assert(endptr == str + 2);
+
+ res = qemu_strtosz(str, NULL);
+ g_assert_cmpint(res, ==, -EINVAL);
}
static void test_qemu_strtosz_erange(void)
diff --git a/util/cutils.c b/util/cutils.c
index 0ac8019..b991623 100644
--- a/util/cutils.c
+++ b/util/cutils.c
@@ -208,7 +208,7 @@ static int64_t suffix_mul(char suffix, int64_t unit)
static int64_t do_strtosz(const char *nptr, char **end,
const char default_suffix, int64_t unit)
{
- int64_t retval = -EINVAL;
+ int64_t retval;
char *endptr;
unsigned char c;
int mul_required = 0;
@@ -217,7 +217,8 @@ static int64_t do_strtosz(const char *nptr, char **end,
errno = 0;
val = strtod(nptr, &endptr);
if (isnan(val) || endptr == nptr || errno != 0) {
- goto fail;
+ retval = -EINVAL;
+ goto out;
}
fraction = modf(val, &integral);
if (fraction != 0) {
@@ -232,17 +233,20 @@ static int64_t do_strtosz(const char *nptr, char **end,
assert(mul >= 0);
}
if (mul == 1 && mul_required) {
- goto fail;
+ retval = -EINVAL;
+ goto out;
}
if ((val * mul >= INT64_MAX) || val < 0) {
retval = -ERANGE;
- goto fail;
+ goto out;
}
retval = val * mul;
-fail:
+out:
if (end) {
*end = endptr;
+ } else if (*endptr) {
+ retval = -EINVAL;
}
return retval;
--
2.7.4
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [Qemu-devel] [PULL 22/24] util/cutils: Return qemu_strtosz*() error and value separately
2017-02-23 19:53 [Qemu-devel] [PULL 00/24] option cutils: Fix and clean up number conversions Markus Armbruster
` (20 preceding siblings ...)
2017-02-23 19:53 ` [Qemu-devel] [PULL 21/24] util/cutils: Let qemu_strtosz*() optionally reject trailing crap Markus Armbruster
@ 2017-02-23 19:54 ` Markus Armbruster
2017-02-23 19:54 ` [Qemu-devel] [PULL 23/24] util/cutils: Change qemu_strtosz*() from int64_t to uint64_t Markus Armbruster
` (3 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Markus Armbruster @ 2017-02-23 19:54 UTC (permalink / raw)
To: qemu-devel
Cc: Dr . David Alan Gilbert, Eduardo Habkost, Kevin Wolf, Max Reitz,
open list:Block layer core
This makes qemu_strtosz(), qemu_strtosz_mebi() and
qemu_strtosz_metric() similar to qemu_strtoi64(), except negative
values are rejected.
Cc: Dr. David Alan Gilbert <dgilbert@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com> (maintainer:X86)
Cc: Kevin Wolf <kwolf@redhat.com> (supporter:Block layer core)
Cc: Max Reitz <mreitz@redhat.com> (supporter:Block layer core)
Cc: qemu-block@nongnu.org (open list:Block layer core)
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Message-Id: <1487708048-2131-23-git-send-email-armbru@redhat.com>
---
hmp.c | 6 +--
hw/misc/ivshmem.c | 7 ++-
include/qemu/cutils.h | 6 +--
monitor.c | 5 ++-
qapi/opts-visitor.c | 5 ++-
qemu-img.c | 10 +++--
qemu-io-cmds.c | 10 +++--
target/i386/cpu.c | 5 ++-
tests/test-cutils.c | 120 ++++++++++++++++++++++++++++++--------------------
util/cutils.c | 22 ++++-----
10 files changed, 119 insertions(+), 77 deletions(-)
diff --git a/hmp.c b/hmp.c
index 2269e8b..d16761f 100644
--- a/hmp.c
+++ b/hmp.c
@@ -1348,7 +1348,7 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict)
long valueint = 0;
Error *err = NULL;
bool use_int_value = false;
- int i;
+ int i, ret;
for (i = 0; i < MIGRATION_PARAMETER__MAX; i++) {
if (strcmp(param, MigrationParameter_lookup[i]) == 0) {
@@ -1384,8 +1384,8 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict)
break;
case MIGRATION_PARAMETER_MAX_BANDWIDTH:
p.has_max_bandwidth = true;
- valuebw = qemu_strtosz_MiB(valuestr, NULL);
- if (valuebw < 0 || (size_t)valuebw != valuebw) {
+ ret = qemu_strtosz_MiB(valuestr, NULL, &valuebw);
+ if (ret < 0 || (size_t)valuebw != valuebw) {
error_setg(&err, "Invalid size %s", valuestr);
goto cleanup;
}
diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c
index 848bebc..80856fd 100644
--- a/hw/misc/ivshmem.c
+++ b/hw/misc/ivshmem.c
@@ -1267,8 +1267,11 @@ static void ivshmem_realize(PCIDevice *dev, Error **errp)
if (s->sizearg == NULL) {
s->legacy_size = 4 << 20; /* 4 MB default */
} else {
- int64_t size = qemu_strtosz_MiB(s->sizearg, NULL);
- if (size < 0 || (size_t)size != size || !is_power_of_2(size)) {
+ int ret;
+ int64_t size;
+
+ ret = qemu_strtosz_MiB(s->sizearg, NULL, &size);
+ if (ret < 0 || (size_t)size != size || !is_power_of_2(size)) {
error_setg(errp, "Invalid size %s", s->sizearg);
return;
}
diff --git a/include/qemu/cutils.h b/include/qemu/cutils.h
index 3fdbb6b..4c68d5c 100644
--- a/include/qemu/cutils.h
+++ b/include/qemu/cutils.h
@@ -139,9 +139,9 @@ int parse_uint(const char *s, unsigned long long *value, char **endptr,
int base);
int parse_uint_full(const char *s, unsigned long long *value, int base);
-int64_t qemu_strtosz(const char *nptr, char **end);
-int64_t qemu_strtosz_MiB(const char *nptr, char **end);
-int64_t qemu_strtosz_metric(const char *nptr, char **end);
+int qemu_strtosz(const char *nptr, char **end, int64_t *result);
+int qemu_strtosz_MiB(const char *nptr, char **end, int64_t *result);
+int qemu_strtosz_metric(const char *nptr, char **end, int64_t *result);
#define K_BYTE (1ULL << 10)
#define M_BYTE (1ULL << 20)
diff --git a/monitor.c b/monitor.c
index c2c1e42..8baeaf0 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2799,6 +2799,7 @@ static QDict *monitor_parse_arguments(Monitor *mon,
break;
case 'o':
{
+ int ret;
int64_t val;
char *end;
@@ -2811,8 +2812,8 @@ static QDict *monitor_parse_arguments(Monitor *mon,
break;
}
}
- val = qemu_strtosz_MiB(p, &end);
- if (val < 0) {
+ ret = qemu_strtosz_MiB(p, &end, &val);
+ if (ret < 0) {
monitor_printf(mon, "invalid size\n");
goto fail;
}
diff --git a/qapi/opts-visitor.c b/qapi/opts-visitor.c
index 911a0ee..aac2e09 100644
--- a/qapi/opts-visitor.c
+++ b/qapi/opts-visitor.c
@@ -482,14 +482,15 @@ opts_type_size(Visitor *v, const char *name, uint64_t *obj, Error **errp)
OptsVisitor *ov = to_ov(v);
const QemuOpt *opt;
int64_t val;
+ int err;
opt = lookup_scalar(ov, name, errp);
if (!opt) {
return;
}
- val = qemu_strtosz(opt->str ? opt->str : "", NULL);
- if (val < 0) {
+ err = qemu_strtosz(opt->str ? opt->str : "", NULL, &val);
+ if (err < 0) {
error_setg(errp, QERR_INVALID_PARAMETER_VALUE, opt->name,
"a size value representible as a non-negative int64");
return;
diff --git a/qemu-img.c b/qemu-img.c
index 39ef581..37d1afb 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -370,10 +370,14 @@ static int add_old_style_options(const char *fmt, QemuOpts *opts,
static int64_t cvtnum(const char *s)
{
- int64_t ret;
+ int err;
+ int64_t value;
- ret = qemu_strtosz(s, NULL);
- return ret;
+ err = qemu_strtosz(s, NULL, &value);
+ if (err < 0) {
+ return err;
+ }
+ return value;
}
static int img_create(int argc, char **argv)
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
index 973eb94..01a6dc6 100644
--- a/qemu-io-cmds.c
+++ b/qemu-io-cmds.c
@@ -137,10 +137,14 @@ static char **breakline(char *input, int *count)
static int64_t cvtnum(const char *s)
{
- int64_t ret;
+ int err;
+ int64_t value;
- ret = qemu_strtosz(s, NULL);
- return ret;
+ err = qemu_strtosz(s, NULL, &value);
+ if (err < 0) {
+ return err;
+ }
+ return value;
}
static void print_cvtnum_err(int64_t rc, const char *arg)
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 58a05ec..d32af97 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -2033,10 +2033,11 @@ static void x86_cpu_parse_featurestr(const char *typename, char *features,
/* Special case: */
if (!strcmp(name, "tsc-freq")) {
+ int ret;
int64_t tsc_freq;
- tsc_freq = qemu_strtosz_metric(val, NULL);
- if (tsc_freq < 0) {
+ ret = qemu_strtosz_metric(val, NULL, &tsc_freq);
+ if (ret < 0) {
error_setg(errp, "bad numerical value %s", val);
return;
}
diff --git a/tests/test-cutils.c b/tests/test-cutils.c
index f2ecb7a..d0137de 100644
--- a/tests/test-cutils.c
+++ b/tests/test-cutils.c
@@ -1373,45 +1373,54 @@ static void test_qemu_strtosz_simple(void)
{
const char *str;
char *endptr = NULL;
- int64_t res;
+ int err;
+ int64_t res = 0xbaadf00d;
str = "0";
- res = qemu_strtosz(str, &endptr);
+ err = qemu_strtosz(str, &endptr, &res);
+ g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 0);
g_assert(endptr == str + 1);
str = "12345";
- res = qemu_strtosz(str, &endptr);
+ err = qemu_strtosz(str, &endptr, &res);
+ g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 12345);
g_assert(endptr == str + 5);
- res = qemu_strtosz(str, NULL);
+ err = qemu_strtosz(str, NULL, &res);
+ g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 12345);
/* Note: precision is 53 bits since we're parsing with strtod() */
str = "9007199254740991"; /* 2^53-1 */
- res = qemu_strtosz(str, &endptr);
+ err = qemu_strtosz(str, &endptr, &res);
+ g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 0x1fffffffffffff);
g_assert(endptr == str + 16);
str = "9007199254740992"; /* 2^53 */
- res = qemu_strtosz(str, &endptr);
+ err = qemu_strtosz(str, &endptr, &res);
+ g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 0x20000000000000);
g_assert(endptr == str + 16);
str = "9007199254740993"; /* 2^53+1 */
- res = qemu_strtosz(str, &endptr);
+ err = qemu_strtosz(str, &endptr, &res);
+ g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 0x20000000000000); /* rounded to 53 bits */
g_assert(endptr == str + 16);
str = "9223372036854774784"; /* 0x7ffffffffffffc00 (53 msbs set) */
- res = qemu_strtosz(str, &endptr);
+ err = qemu_strtosz(str, &endptr, &res);
+ g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 0x7ffffffffffffc00);
g_assert(endptr == str + 19);
str = "9223372036854775295"; /* 0x7ffffffffffffdff */
- res = qemu_strtosz(str, &endptr);
+ err = qemu_strtosz(str, &endptr, &res);
+ g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 0x7ffffffffffffc00); /* rounded to 53 bits */
g_assert(endptr == str + 19);
@@ -1429,39 +1438,48 @@ static void test_qemu_strtosz_units(void)
const char *t = "1T";
const char *p = "1P";
const char *e = "1E";
+ int err;
char *endptr = NULL;
- int64_t res;
+ int64_t res = 0xbaadf00d;
/* default is M */
- res = qemu_strtosz_MiB(none, &endptr);
+ err = qemu_strtosz_MiB(none, &endptr, &res);
+ g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, M_BYTE);
g_assert(endptr == none + 1);
- res = qemu_strtosz(b, &endptr);
+ err = qemu_strtosz(b, &endptr, &res);
+ g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 1);
g_assert(endptr == b + 2);
- res = qemu_strtosz(k, &endptr);
+ err = qemu_strtosz(k, &endptr, &res);
+ g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, K_BYTE);
g_assert(endptr == k + 2);
- res = qemu_strtosz(m, &endptr);
+ err = qemu_strtosz(m, &endptr, &res);
+ g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, M_BYTE);
g_assert(endptr == m + 2);
- res = qemu_strtosz(g, &endptr);
+ err = qemu_strtosz(g, &endptr, &res);
+ g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, G_BYTE);
g_assert(endptr == g + 2);
- res = qemu_strtosz(t, &endptr);
+ err = qemu_strtosz(t, &endptr, &res);
+ g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, T_BYTE);
g_assert(endptr == t + 2);
- res = qemu_strtosz(p, &endptr);
+ err = qemu_strtosz(p, &endptr, &res);
+ g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, P_BYTE);
g_assert(endptr == p + 2);
- res = qemu_strtosz(e, &endptr);
+ err = qemu_strtosz(e, &endptr, &res);
+ g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, E_BYTE);
g_assert(endptr == e + 2);
}
@@ -1469,10 +1487,12 @@ static void test_qemu_strtosz_units(void)
static void test_qemu_strtosz_float(void)
{
const char *str = "12.345M";
+ int err;
char *endptr = NULL;
- int64_t res;
+ int64_t res = 0xbaadf00d;
- res = qemu_strtosz(str, &endptr);
+ err = qemu_strtosz(str, &endptr, &res);
+ g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 12.345 * M_BYTE);
g_assert(endptr == str + 7);
}
@@ -1481,21 +1501,22 @@ static void test_qemu_strtosz_invalid(void)
{
const char *str;
char *endptr = NULL;
- int64_t res;
+ int err;
+ int64_t res = 0xbaadf00d;
str = "";
- res = qemu_strtosz(str, &endptr);
- g_assert_cmpint(res, ==, -EINVAL);
+ err = qemu_strtosz(str, &endptr, &res);
+ g_assert_cmpint(err, ==, -EINVAL);
g_assert(endptr == str);
str = " \t ";
- res = qemu_strtosz(str, &endptr);
- g_assert_cmpint(res, ==, -EINVAL);
+ err = qemu_strtosz(str, &endptr, &res);
+ g_assert_cmpint(err, ==, -EINVAL);
g_assert(endptr == str);
str = "crap";
- res = qemu_strtosz(str, &endptr);
- g_assert_cmpint(res, ==, -EINVAL);
+ err = qemu_strtosz(str, &endptr, &res);
+ g_assert_cmpint(err, ==, -EINVAL);
g_assert(endptr == str);
}
@@ -1503,64 +1524,69 @@ static void test_qemu_strtosz_trailing(void)
{
const char *str;
char *endptr = NULL;
- int64_t res;
+ int err;
+ int64_t res = 0xbaadf00d;
str = "123xxx";
- res = qemu_strtosz_MiB(str, &endptr);
+ err = qemu_strtosz_MiB(str, &endptr, &res);
g_assert_cmpint(res, ==, 123 * M_BYTE);
g_assert(endptr == str + 3);
- res = qemu_strtosz(str, NULL);
- g_assert_cmpint(res, ==, -EINVAL);
+ err = qemu_strtosz(str, NULL, &res);
+ g_assert_cmpint(err, ==, -EINVAL);
str = "1kiB";
- res = qemu_strtosz(str, &endptr);
+ err = qemu_strtosz(str, &endptr, &res);
+ g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 1024);
g_assert(endptr == str + 2);
- res = qemu_strtosz(str, NULL);
- g_assert_cmpint(res, ==, -EINVAL);
+ err = qemu_strtosz(str, NULL, &res);
+ g_assert_cmpint(err, ==, -EINVAL);
}
static void test_qemu_strtosz_erange(void)
{
const char *str;
char *endptr = NULL;
- int64_t res;
+ int err;
+ int64_t res = 0xbaadf00d;
str = "-1";
- res = qemu_strtosz(str, &endptr);
- g_assert_cmpint(res, ==, -ERANGE);
+ err = qemu_strtosz(str, &endptr, &res);
+ g_assert_cmpint(err, ==, -ERANGE);
g_assert(endptr == str + 2);
str = "9223372036854775296"; /* 0x7ffffffffffffe00 */
- res = qemu_strtosz(str, &endptr);
- g_assert_cmpint(res, ==, -ERANGE);
+ err = qemu_strtosz(str, &endptr, &res);
+ g_assert_cmpint(err, ==, -ERANGE);
g_assert(endptr == str + 19);
str = "9223372036854775807"; /* 2^63-1 */
- res = qemu_strtosz(str, &endptr);
- g_assert_cmpint(res, ==, -ERANGE);
+ err = qemu_strtosz(str, &endptr, &res);
+ g_assert_cmpint(err, ==, -ERANGE);
g_assert(endptr == str + 19);
str = "9223372036854775808"; /* 2^63 */
- res = qemu_strtosz(str, &endptr);
- g_assert_cmpint(res, ==, -ERANGE);
+ err = qemu_strtosz(str, &endptr, &res);
+ g_assert_cmpint(err, ==, -ERANGE);
g_assert(endptr == str + 19);
str = "10E";
- res = qemu_strtosz(str, &endptr);
- g_assert_cmpint(res, ==, -ERANGE);
+ err = qemu_strtosz(str, &endptr, &res);
+ g_assert_cmpint(err, ==, -ERANGE);
g_assert(endptr == str + 3);
}
static void test_qemu_strtosz_metric(void)
{
const char *str = "12345k";
+ int err;
char *endptr = NULL;
- int64_t res;
+ int64_t res = 0xbaadf00d;
- res = qemu_strtosz_metric(str, &endptr);
+ err = qemu_strtosz_metric(str, &endptr, &res);
+ g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 12345000);
g_assert(endptr == str + 6);
}
diff --git a/util/cutils.c b/util/cutils.c
index b991623..7088ddc 100644
--- a/util/cutils.c
+++ b/util/cutils.c
@@ -205,10 +205,11 @@ static int64_t suffix_mul(char suffix, int64_t unit)
* in *end, if not NULL. Return -ERANGE on overflow, Return -EINVAL on
* other error.
*/
-static int64_t do_strtosz(const char *nptr, char **end,
- const char default_suffix, int64_t unit)
+static int do_strtosz(const char *nptr, char **end,
+ const char default_suffix, int64_t unit,
+ int64_t *result)
{
- int64_t retval;
+ int retval;
char *endptr;
unsigned char c;
int mul_required = 0;
@@ -240,7 +241,8 @@ static int64_t do_strtosz(const char *nptr, char **end,
retval = -ERANGE;
goto out;
}
- retval = val * mul;
+ *result = val * mul;
+ retval = 0;
out:
if (end) {
@@ -252,19 +254,19 @@ out:
return retval;
}
-int64_t qemu_strtosz(const char *nptr, char **end)
+int qemu_strtosz(const char *nptr, char **end, int64_t *result)
{
- return do_strtosz(nptr, end, 'B', 1024);
+ return do_strtosz(nptr, end, 'B', 1024, result);
}
-int64_t qemu_strtosz_MiB(const char *nptr, char **end)
+int qemu_strtosz_MiB(const char *nptr, char **end, int64_t *result)
{
- return do_strtosz(nptr, end, 'M', 1024);
+ return do_strtosz(nptr, end, 'M', 1024, result);
}
-int64_t qemu_strtosz_metric(const char *nptr, char **end)
+int qemu_strtosz_metric(const char *nptr, char **end, int64_t *result)
{
- return do_strtosz(nptr, end, 'B', 1000);
+ return do_strtosz(nptr, end, 'B', 1000, result);
}
/**
--
2.7.4
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [Qemu-devel] [PULL 23/24] util/cutils: Change qemu_strtosz*() from int64_t to uint64_t
2017-02-23 19:53 [Qemu-devel] [PULL 00/24] option cutils: Fix and clean up number conversions Markus Armbruster
` (21 preceding siblings ...)
2017-02-23 19:54 ` [Qemu-devel] [PULL 22/24] util/cutils: Return qemu_strtosz*() error and value separately Markus Armbruster
@ 2017-02-23 19:54 ` Markus Armbruster
2017-02-23 19:54 ` [Qemu-devel] [PULL 24/24] option: Fix checking of sizes for overflow and trailing crap Markus Armbruster
` (2 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Markus Armbruster @ 2017-02-23 19:54 UTC (permalink / raw)
To: qemu-devel
Cc: Dr . David Alan Gilbert, Eduardo Habkost, Kevin Wolf, Max Reitz,
open list:Block layer core
This will permit its use in parse_option_size().
Cc: Dr. David Alan Gilbert <dgilbert@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com> (maintainer:X86)
Cc: Kevin Wolf <kwolf@redhat.com> (supporter:Block layer core)
Cc: Max Reitz <mreitz@redhat.com> (supporter:Block layer core)
Cc: qemu-block@nongnu.org (open list:Block layer core)
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Message-Id: <1487708048-2131-24-git-send-email-armbru@redhat.com>
---
hmp.c | 5 +++--
hw/misc/ivshmem.c | 2 +-
include/qemu/cutils.h | 6 +++---
monitor.c | 4 ++--
qapi/opts-visitor.c | 6 ++----
qemu-img.c | 5 ++++-
qemu-io-cmds.c | 5 ++++-
target/i386/cpu.c | 4 ++--
tests/test-cutils.c | 40 ++++++++++++++++++++--------------------
util/cutils.c | 14 +++++++++-----
10 files changed, 50 insertions(+), 41 deletions(-)
diff --git a/hmp.c b/hmp.c
index d16761f..83e287e 100644
--- a/hmp.c
+++ b/hmp.c
@@ -1344,7 +1344,7 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict)
{
const char *param = qdict_get_str(qdict, "parameter");
const char *valuestr = qdict_get_str(qdict, "value");
- int64_t valuebw = 0;
+ uint64_t valuebw = 0;
long valueint = 0;
Error *err = NULL;
bool use_int_value = false;
@@ -1385,7 +1385,8 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict)
case MIGRATION_PARAMETER_MAX_BANDWIDTH:
p.has_max_bandwidth = true;
ret = qemu_strtosz_MiB(valuestr, NULL, &valuebw);
- if (ret < 0 || (size_t)valuebw != valuebw) {
+ if (ret < 0 || valuebw > INT64_MAX
+ || (size_t)valuebw != valuebw) {
error_setg(&err, "Invalid size %s", valuestr);
goto cleanup;
}
diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c
index 80856fd..82ce837 100644
--- a/hw/misc/ivshmem.c
+++ b/hw/misc/ivshmem.c
@@ -1268,7 +1268,7 @@ static void ivshmem_realize(PCIDevice *dev, Error **errp)
s->legacy_size = 4 << 20; /* 4 MB default */
} else {
int ret;
- int64_t size;
+ uint64_t size;
ret = qemu_strtosz_MiB(s->sizearg, NULL, &size);
if (ret < 0 || (size_t)size != size || !is_power_of_2(size)) {
diff --git a/include/qemu/cutils.h b/include/qemu/cutils.h
index 4c68d5c..f0878ea 100644
--- a/include/qemu/cutils.h
+++ b/include/qemu/cutils.h
@@ -139,9 +139,9 @@ int parse_uint(const char *s, unsigned long long *value, char **endptr,
int base);
int parse_uint_full(const char *s, unsigned long long *value, int base);
-int qemu_strtosz(const char *nptr, char **end, int64_t *result);
-int qemu_strtosz_MiB(const char *nptr, char **end, int64_t *result);
-int qemu_strtosz_metric(const char *nptr, char **end, int64_t *result);
+int qemu_strtosz(const char *nptr, char **end, uint64_t *result);
+int qemu_strtosz_MiB(const char *nptr, char **end, uint64_t *result);
+int qemu_strtosz_metric(const char *nptr, char **end, uint64_t *result);
#define K_BYTE (1ULL << 10)
#define M_BYTE (1ULL << 20)
diff --git a/monitor.c b/monitor.c
index 8baeaf0..4ac2702 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2800,7 +2800,7 @@ static QDict *monitor_parse_arguments(Monitor *mon,
case 'o':
{
int ret;
- int64_t val;
+ uint64_t val;
char *end;
while (qemu_isspace(*p)) {
@@ -2813,7 +2813,7 @@ static QDict *monitor_parse_arguments(Monitor *mon,
}
}
ret = qemu_strtosz_MiB(p, &end, &val);
- if (ret < 0) {
+ if (ret < 0 || val > INT64_MAX) {
monitor_printf(mon, "invalid size\n");
goto fail;
}
diff --git a/qapi/opts-visitor.c b/qapi/opts-visitor.c
index aac2e09..a0a7c0e 100644
--- a/qapi/opts-visitor.c
+++ b/qapi/opts-visitor.c
@@ -481,7 +481,6 @@ opts_type_size(Visitor *v, const char *name, uint64_t *obj, Error **errp)
{
OptsVisitor *ov = to_ov(v);
const QemuOpt *opt;
- int64_t val;
int err;
opt = lookup_scalar(ov, name, errp);
@@ -489,14 +488,13 @@ opts_type_size(Visitor *v, const char *name, uint64_t *obj, Error **errp)
return;
}
- err = qemu_strtosz(opt->str ? opt->str : "", NULL, &val);
+ err = qemu_strtosz(opt->str ? opt->str : "", NULL, obj);
if (err < 0) {
error_setg(errp, QERR_INVALID_PARAMETER_VALUE, opt->name,
- "a size value representible as a non-negative int64");
+ "a size value");
return;
}
- *obj = val;
processed(ov, name);
}
diff --git a/qemu-img.c b/qemu-img.c
index 37d1afb..df3aefd 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -371,12 +371,15 @@ static int add_old_style_options(const char *fmt, QemuOpts *opts,
static int64_t cvtnum(const char *s)
{
int err;
- int64_t value;
+ uint64_t value;
err = qemu_strtosz(s, NULL, &value);
if (err < 0) {
return err;
}
+ if (value > INT64_MAX) {
+ return -ERANGE;
+ }
return value;
}
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
index 01a6dc6..7ac1576 100644
--- a/qemu-io-cmds.c
+++ b/qemu-io-cmds.c
@@ -138,12 +138,15 @@ static char **breakline(char *input, int *count)
static int64_t cvtnum(const char *s)
{
int err;
- int64_t value;
+ uint64_t value;
err = qemu_strtosz(s, NULL, &value);
if (err < 0) {
return err;
}
+ if (value > INT64_MAX) {
+ return -ERANGE;
+ }
return value;
}
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index d32af97..b6f157d 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -2034,10 +2034,10 @@ static void x86_cpu_parse_featurestr(const char *typename, char *features,
/* Special case: */
if (!strcmp(name, "tsc-freq")) {
int ret;
- int64_t tsc_freq;
+ uint64_t tsc_freq;
ret = qemu_strtosz_metric(val, NULL, &tsc_freq);
- if (ret < 0) {
+ if (ret < 0 || tsc_freq > INT64_MAX) {
error_setg(errp, "bad numerical value %s", val);
return;
}
diff --git a/tests/test-cutils.c b/tests/test-cutils.c
index d0137de..f64a49b 100644
--- a/tests/test-cutils.c
+++ b/tests/test-cutils.c
@@ -1374,7 +1374,7 @@ static void test_qemu_strtosz_simple(void)
const char *str;
char *endptr = NULL;
int err;
- int64_t res = 0xbaadf00d;
+ uint64_t res = 0xbaadf00d;
str = "0";
err = qemu_strtosz(str, &endptr, &res);
@@ -1412,17 +1412,17 @@ static void test_qemu_strtosz_simple(void)
g_assert_cmpint(res, ==, 0x20000000000000); /* rounded to 53 bits */
g_assert(endptr == str + 16);
- str = "9223372036854774784"; /* 0x7ffffffffffffc00 (53 msbs set) */
+ str = "18446744073709549568"; /* 0xfffffffffffff800 (53 msbs set) */
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, 0);
- g_assert_cmpint(res, ==, 0x7ffffffffffffc00);
- g_assert(endptr == str + 19);
+ g_assert_cmpint(res, ==, 0xfffffffffffff800);
+ g_assert(endptr == str + 20);
- str = "9223372036854775295"; /* 0x7ffffffffffffdff */
+ str = "18446744073709550591"; /* 0xfffffffffffffbff */
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, 0);
- g_assert_cmpint(res, ==, 0x7ffffffffffffc00); /* rounded to 53 bits */
- g_assert(endptr == str + 19);
+ g_assert_cmpint(res, ==, 0xfffffffffffff800); /* rounded to 53 bits */
+ g_assert(endptr == str + 20);
/* 0x7ffffffffffffe00..0x7fffffffffffffff get rounded to
* 0x8000000000000000, thus -ERANGE; see test_qemu_strtosz_erange() */
@@ -1440,7 +1440,7 @@ static void test_qemu_strtosz_units(void)
const char *e = "1E";
int err;
char *endptr = NULL;
- int64_t res = 0xbaadf00d;
+ uint64_t res = 0xbaadf00d;
/* default is M */
err = qemu_strtosz_MiB(none, &endptr, &res);
@@ -1489,7 +1489,7 @@ static void test_qemu_strtosz_float(void)
const char *str = "12.345M";
int err;
char *endptr = NULL;
- int64_t res = 0xbaadf00d;
+ uint64_t res = 0xbaadf00d;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, 0);
@@ -1502,7 +1502,7 @@ static void test_qemu_strtosz_invalid(void)
const char *str;
char *endptr = NULL;
int err;
- int64_t res = 0xbaadf00d;
+ uint64_t res = 0xbaadf00d;
str = "";
err = qemu_strtosz(str, &endptr, &res);
@@ -1525,7 +1525,7 @@ static void test_qemu_strtosz_trailing(void)
const char *str;
char *endptr = NULL;
int err;
- int64_t res = 0xbaadf00d;
+ uint64_t res = 0xbaadf00d;
str = "123xxx";
err = qemu_strtosz_MiB(str, &endptr, &res);
@@ -1550,29 +1550,29 @@ static void test_qemu_strtosz_erange(void)
const char *str;
char *endptr = NULL;
int err;
- int64_t res = 0xbaadf00d;
+ uint64_t res = 0xbaadf00d;
str = "-1";
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, -ERANGE);
g_assert(endptr == str + 2);
- str = "9223372036854775296"; /* 0x7ffffffffffffe00 */
+ str = "18446744073709550592"; /* 0xfffffffffffffc00 */
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, -ERANGE);
- g_assert(endptr == str + 19);
+ g_assert(endptr == str + 20);
- str = "9223372036854775807"; /* 2^63-1 */
+ str = "18446744073709551615"; /* 2^64-1 */
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, -ERANGE);
- g_assert(endptr == str + 19);
+ g_assert(endptr == str + 20);
- str = "9223372036854775808"; /* 2^63 */
+ str = "18446744073709551616"; /* 2^64 */
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, -ERANGE);
- g_assert(endptr == str + 19);
+ g_assert(endptr == str + 20);
- str = "10E";
+ str = "20E";
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, -ERANGE);
g_assert(endptr == str + 3);
@@ -1583,7 +1583,7 @@ static void test_qemu_strtosz_metric(void)
const char *str = "12345k";
int err;
char *endptr = NULL;
- int64_t res = 0xbaadf00d;
+ uint64_t res = 0xbaadf00d;
err = qemu_strtosz_metric(str, &endptr, &res);
g_assert_cmpint(err, ==, 0);
diff --git a/util/cutils.c b/util/cutils.c
index 7088ddc..50ad179 100644
--- a/util/cutils.c
+++ b/util/cutils.c
@@ -207,7 +207,7 @@ static int64_t suffix_mul(char suffix, int64_t unit)
*/
static int do_strtosz(const char *nptr, char **end,
const char default_suffix, int64_t unit,
- int64_t *result)
+ uint64_t *result)
{
int retval;
char *endptr;
@@ -237,7 +237,11 @@ static int do_strtosz(const char *nptr, char **end,
retval = -EINVAL;
goto out;
}
- if ((val * mul >= INT64_MAX) || val < 0) {
+ /*
+ * Values >= 0xfffffffffffffc00 overflow uint64_t after their trip
+ * through double (53 bits of precision).
+ */
+ if ((val * mul >= 0xfffffffffffffc00) || val < 0) {
retval = -ERANGE;
goto out;
}
@@ -254,17 +258,17 @@ out:
return retval;
}
-int qemu_strtosz(const char *nptr, char **end, int64_t *result)
+int qemu_strtosz(const char *nptr, char **end, uint64_t *result)
{
return do_strtosz(nptr, end, 'B', 1024, result);
}
-int qemu_strtosz_MiB(const char *nptr, char **end, int64_t *result)
+int qemu_strtosz_MiB(const char *nptr, char **end, uint64_t *result)
{
return do_strtosz(nptr, end, 'M', 1024, result);
}
-int qemu_strtosz_metric(const char *nptr, char **end, int64_t *result)
+int qemu_strtosz_metric(const char *nptr, char **end, uint64_t *result)
{
return do_strtosz(nptr, end, 'B', 1000, result);
}
--
2.7.4
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [Qemu-devel] [PULL 24/24] option: Fix checking of sizes for overflow and trailing crap
2017-02-23 19:53 [Qemu-devel] [PULL 00/24] option cutils: Fix and clean up number conversions Markus Armbruster
` (22 preceding siblings ...)
2017-02-23 19:54 ` [Qemu-devel] [PULL 23/24] util/cutils: Change qemu_strtosz*() from int64_t to uint64_t Markus Armbruster
@ 2017-02-23 19:54 ` Markus Armbruster
2017-02-23 20:37 ` [Qemu-devel] [PULL 00/24] option cutils: Fix and clean up number conversions no-reply
2017-02-25 16:37 ` Peter Maydell
25 siblings, 0 replies; 27+ messages in thread
From: Markus Armbruster @ 2017-02-23 19:54 UTC (permalink / raw)
To: qemu-devel
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>
---
tests/test-qemu-opts.c | 21 +++++++++------------
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 8b92f7b..c46ef31 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 273d00d..419f252 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)
--
2.7.4
^ permalink raw reply related [flat|nested] 27+ messages in thread
* Re: [Qemu-devel] [PULL 00/24] option cutils: Fix and clean up number conversions
2017-02-23 19:53 [Qemu-devel] [PULL 00/24] option cutils: Fix and clean up number conversions Markus Armbruster
` (23 preceding siblings ...)
2017-02-23 19:54 ` [Qemu-devel] [PULL 24/24] option: Fix checking of sizes for overflow and trailing crap Markus Armbruster
@ 2017-02-23 20:37 ` no-reply
2017-02-25 16:37 ` Peter Maydell
25 siblings, 0 replies; 27+ messages in thread
From: no-reply @ 2017-02-23 20:37 UTC (permalink / raw)
To: armbru; +Cc: famz, qemu-devel
Hi,
This series seems to have some coding style problems. See output below for
more information:
Message-id: 1487879642-16139-1-git-send-email-armbru@redhat.com
Type: series
Subject: [Qemu-devel] [PULL 00/24] option cutils: Fix and clean up number conversions
=== TEST SCRIPT BEGIN ===
#!/bin/bash
BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0
# Useful git options
git config --local diff.renamelimit 0
git config --local diff.renames True
commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
failed=1
echo
fi
n=$((n+1))
done
exit $failed
=== TEST SCRIPT END ===
Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
* [new tag] patchew/1487879642-16139-1-git-send-email-armbru@redhat.com -> patchew/1487879642-16139-1-git-send-email-armbru@redhat.com
Switched to a new branch 'test'
6c2dc6b option: Fix checking of sizes for overflow and trailing crap
efb849e util/cutils: Change qemu_strtosz*() from int64_t to uint64_t
a3c2af8 util/cutils: Return qemu_strtosz*() error and value separately
e88e2c7 util/cutils: Let qemu_strtosz*() optionally reject trailing crap
ee039b6 qemu-img: Wrap cvtnum() around qemu_strtosz()
031b4f2 test-cutils: Drop suffix from test_qemu_strtosz_simple()
e59d8e6 test-cutils: Use qemu_strtosz() more often
693870b util/cutils: Drop QEMU_STRTOSZ_DEFSUFFIX_* macros
7878803 util/cutils: New qemu_strtosz()
0f70e58 util/cutils: Rename qemu_strtosz() to qemu_strtosz_MiB()
a8c80cd util/cutils: New qemu_strtosz_metric()
9f9041c test-cutils: Cover qemu_strtosz() around range limits
b6e3a34 test-cutils: Cover qemu_strtosz() with trailing crap
68347a8 test-cutils: Cover qemu_strtosz() invalid input
a54e5e3 test-cutils: Add missing qemu_strtosz()... endptr checks
5223692 option: Fix to reject invalid and overflowing numbers
3c3b278 util/cutils: Clean up control flow around qemu_strtol() a bit
f8fb787 util/cutils: Clean up variable names around qemu_strtol()
3f76906 util/cutils: Rename qemu_strtoll(), qemu_strtoull()
6caaa68 util/cutils: Rewrite documentation of qemu_strtol() & friends
a81892f test-cutils: Clean up qemu_strtoul() result checks
cc3ccd8 test-cutils: Add missing qemu_strtol()... endptr checks
06d7d7e option: Assert value string isn't null
5202d75 test-qemu-opts: Cover qemu_opts_parse()
=== OUTPUT BEGIN ===
Checking PATCH 1/24: test-qemu-opts: Cover qemu_opts_parse()...
Checking PATCH 2/24: option: Assert value string isn't null...
ERROR: consider using qemu_strtoull in preference to strtoull
#77: FILE: util/qemu-option.c:147:
+ number = strtoull(value, &postfix, 0);
total: 1 errors, 0 warnings, 117 lines checked
Your patch has style problems, please review. If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 3/24: test-cutils: Add missing qemu_strtol()... endptr checks...
Checking PATCH 4/24: test-cutils: Clean up qemu_strtoul() result checks...
Checking PATCH 5/24: util/cutils: Rewrite documentation of qemu_strtol() & friends...
Checking PATCH 6/24: util/cutils: Rename qemu_strtoll(), qemu_strtoull()...
Checking PATCH 7/24: util/cutils: Clean up variable names around qemu_strtol()...
ERROR: consider using qemu_strtol in preference to strtol
#78: FILE: util/cutils.c:316:
+ *result = strtol(nptr, &ep, base);
ERROR: consider using qemu_strtoul in preference to strtoul
#97: FILE: util/cutils.c:359:
+ *result = strtoul(nptr, &ep, base);
ERROR: consider using qemu_strtoll in preference to strtoll
#122: FILE: util/cutils.c:388:
+ *result = strtoll(nptr, &ep, base);
ERROR: consider using qemu_strtoull in preference to strtoull
#141: FILE: util/cutils.c:412:
+ *result = strtoull(nptr, &ep, base);
total: 4 errors, 0 warnings, 110 lines checked
Your patch has style problems, please review. If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 8/24: util/cutils: Clean up control flow around qemu_strtol() a bit...
ERROR: consider using qemu_strtol in preference to strtol
#83: FILE: util/cutils.c:322:
+ *result = strtol(nptr, &ep, base);
ERROR: consider using qemu_strtoul in preference to strtoul
#111: FILE: util/cutils.c:364:
+ *result = strtoul(nptr, &ep, base);
ERROR: consider using qemu_strtoll in preference to strtoll
#143: FILE: util/cutils.c:392:
+ *result = strtoll(nptr, &ep, base);
ERROR: consider using qemu_strtoull in preference to strtoull
#173: FILE: util/cutils.c:415:
+ *result = strtoull(nptr, &ep, base);
total: 4 errors, 0 warnings, 140 lines checked
Your patch has style problems, please review. If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 9/24: option: Fix to reject invalid and overflowing numbers...
Checking PATCH 10/24: test-cutils: Add missing qemu_strtosz()... endptr checks...
Checking PATCH 11/24: test-cutils: Cover qemu_strtosz() invalid input...
Checking PATCH 12/24: test-cutils: Cover qemu_strtosz() with trailing crap...
Checking PATCH 13/24: test-cutils: Cover qemu_strtosz() around range limits...
Checking PATCH 14/24: util/cutils: New qemu_strtosz_metric()...
Checking PATCH 15/24: util/cutils: Rename qemu_strtosz() to qemu_strtosz_MiB()...
Checking PATCH 16/24: util/cutils: New qemu_strtosz()...
Checking PATCH 17/24: util/cutils: Drop QEMU_STRTOSZ_DEFSUFFIX_* macros...
Checking PATCH 18/24: test-cutils: Use qemu_strtosz() more often...
Checking PATCH 19/24: test-cutils: Drop suffix from test_qemu_strtosz_simple()...
Checking PATCH 20/24: qemu-img: Wrap cvtnum() around qemu_strtosz()...
Checking PATCH 21/24: util/cutils: Let qemu_strtosz*() optionally reject trailing crap...
Checking PATCH 22/24: util/cutils: Return qemu_strtosz*() error and value separately...
Checking PATCH 23/24: util/cutils: Change qemu_strtosz*() from int64_t to uint64_t...
Checking PATCH 24/24: option: Fix checking of sizes for overflow and trailing crap...
=== OUTPUT END ===
Test command exited with code: 1
---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@freelists.org
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [Qemu-devel] [PULL 00/24] option cutils: Fix and clean up number conversions
2017-02-23 19:53 [Qemu-devel] [PULL 00/24] option cutils: Fix and clean up number conversions Markus Armbruster
` (24 preceding siblings ...)
2017-02-23 20:37 ` [Qemu-devel] [PULL 00/24] option cutils: Fix and clean up number conversions no-reply
@ 2017-02-25 16:37 ` Peter Maydell
25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2017-02-25 16:37 UTC (permalink / raw)
To: Markus Armbruster; +Cc: QEMU Developers
On 23 February 2017 at 19:53, Markus Armbruster <armbru@redhat.com> wrote:
> QemuOpts has its own code to convert strings to numbers, and being
> QemuOpts, it gets it wrong. util/cutils is less wrong. Fix it up
> some, and reuse it for QemuOpts.
>
> The following changes since commit 10f25e4844cb9b3f02fb032f88051dd5b65b4206:
>
> Merge remote-tracking branch 'remotes/yongbok/tags/mips-20170222' into staging (2017-02-23 09:59:40 +0000)
>
> are available in the git repository at:
>
> git://repo.or.cz/qemu/armbru.git tags/pull-util-2017-02-23
>
> for you to fetch changes up to 75cdcd1553e74b5edc58aed23e3b2da8dabb1876:
>
> option: Fix checking of sizes for overflow and trailing crap (2017-02-23 20:35:36 +0100)
>
> ----------------------------------------------------------------
> option cutils: Fix and clean up number conversions
>
Applied, thanks.
-- PMM
^ permalink raw reply [flat|nested] 27+ messages in thread
end of thread, other threads:[~2017-02-25 16:37 UTC | newest]
Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-02-23 19:53 [Qemu-devel] [PULL 00/24] option cutils: Fix and clean up number conversions Markus Armbruster
2017-02-23 19:53 ` [Qemu-devel] [PULL 01/24] test-qemu-opts: Cover qemu_opts_parse() Markus Armbruster
2017-02-23 19:53 ` [Qemu-devel] [PULL 02/24] option: Assert value string isn't null Markus Armbruster
2017-02-23 19:53 ` [Qemu-devel] [PULL 03/24] test-cutils: Add missing qemu_strtol()... endptr checks Markus Armbruster
2017-02-23 19:53 ` [Qemu-devel] [PULL 04/24] test-cutils: Clean up qemu_strtoul() result checks Markus Armbruster
2017-02-23 19:53 ` [Qemu-devel] [PULL 05/24] util/cutils: Rewrite documentation of qemu_strtol() & friends Markus Armbruster
2017-02-23 19:53 ` [Qemu-devel] [PULL 06/24] util/cutils: Rename qemu_strtoll(), qemu_strtoull() Markus Armbruster
2017-02-23 19:53 ` [Qemu-devel] [PULL 07/24] util/cutils: Clean up variable names around qemu_strtol() Markus Armbruster
2017-02-23 19:53 ` [Qemu-devel] [PULL 08/24] util/cutils: Clean up control flow around qemu_strtol() a bit Markus Armbruster
2017-02-23 19:53 ` [Qemu-devel] [PULL 09/24] option: Fix to reject invalid and overflowing numbers Markus Armbruster
2017-02-23 19:53 ` [Qemu-devel] [PULL 10/24] test-cutils: Add missing qemu_strtosz()... endptr checks Markus Armbruster
2017-02-23 19:53 ` [Qemu-devel] [PULL 11/24] test-cutils: Cover qemu_strtosz() invalid input Markus Armbruster
2017-02-23 19:53 ` [Qemu-devel] [PULL 12/24] test-cutils: Cover qemu_strtosz() with trailing crap Markus Armbruster
2017-02-23 19:53 ` [Qemu-devel] [PULL 13/24] test-cutils: Cover qemu_strtosz() around range limits Markus Armbruster
2017-02-23 19:53 ` [Qemu-devel] [PULL 14/24] util/cutils: New qemu_strtosz_metric() Markus Armbruster
2017-02-23 19:53 ` [Qemu-devel] [PULL 15/24] util/cutils: Rename qemu_strtosz() to qemu_strtosz_MiB() Markus Armbruster
2017-02-23 19:53 ` [Qemu-devel] [PULL 16/24] util/cutils: New qemu_strtosz() Markus Armbruster
2017-02-23 19:53 ` [Qemu-devel] [PULL 17/24] util/cutils: Drop QEMU_STRTOSZ_DEFSUFFIX_* macros Markus Armbruster
2017-02-23 19:53 ` [Qemu-devel] [PULL 18/24] test-cutils: Use qemu_strtosz() more often Markus Armbruster
2017-02-23 19:53 ` [Qemu-devel] [PULL 19/24] test-cutils: Drop suffix from test_qemu_strtosz_simple() Markus Armbruster
2017-02-23 19:53 ` [Qemu-devel] [PULL 20/24] qemu-img: Wrap cvtnum() around qemu_strtosz() Markus Armbruster
2017-02-23 19:53 ` [Qemu-devel] [PULL 21/24] util/cutils: Let qemu_strtosz*() optionally reject trailing crap Markus Armbruster
2017-02-23 19:54 ` [Qemu-devel] [PULL 22/24] util/cutils: Return qemu_strtosz*() error and value separately Markus Armbruster
2017-02-23 19:54 ` [Qemu-devel] [PULL 23/24] util/cutils: Change qemu_strtosz*() from int64_t to uint64_t Markus Armbruster
2017-02-23 19:54 ` [Qemu-devel] [PULL 24/24] option: Fix checking of sizes for overflow and trailing crap Markus Armbruster
2017-02-23 20:37 ` [Qemu-devel] [PULL 00/24] option cutils: Fix and clean up number conversions no-reply
2017-02-25 16:37 ` Peter Maydell
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.