All of lore.kernel.org
 help / color / mirror / Atom feed
* [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.