[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v1 13/14] utils: Tighter tests for qemu_strtosz
From: |
Alex Bennée |
Subject: |
[PATCH v1 13/14] utils: Tighter tests for qemu_strtosz |
Date: |
Sat, 20 Mar 2021 13:37:05 +0000 |
From: Eric Blake <eblake@redhat.com>
Our tests were not validating the return value in all cases, nor was
it guaranteeing our documented claim that 'res' is unchanged on error.
For that matter, it wasn't as thorough as the existing tests for
qemu_strtoi() and friends for proving that endptr and res are sanely
set. Enhancing the test found one case where we violated our
documentation: namely, when failing with EINVAL when endptr is NULL,
we shouldn't modify res.
Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-Id: <20210317143325.2165821-2-eblake@redhat.com>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
---
tests/unit/test-cutils.c | 117 +++++++++++++++++++++++++++++++++++++--
util/cutils.c | 4 +-
2 files changed, 114 insertions(+), 7 deletions(-)
diff --git a/tests/unit/test-cutils.c b/tests/unit/test-cutils.c
index e025b54c05..5908de4fd0 100644
--- a/tests/unit/test-cutils.c
+++ b/tests/unit/test-cutils.c
@@ -1952,9 +1952,11 @@ static void test_qemu_strtosz_simple(void)
const char *str;
const char *endptr;
int err;
- uint64_t res = 0xbaadf00d;
+ uint64_t res;
str = "0";
+ endptr = str;
+ res = 0xbaadf00d;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 0);
@@ -1962,6 +1964,8 @@ static void test_qemu_strtosz_simple(void)
/* Leading 0 gives decimal results, not octal */
str = "08";
+ endptr = str;
+ res = 0xbaadf00d;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 8);
@@ -1969,46 +1973,61 @@ static void test_qemu_strtosz_simple(void)
/* Leading space is ignored */
str = " 12345";
+ endptr = str;
+ res = 0xbaadf00d;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 12345);
g_assert(endptr == str + 6);
+ res = 0xbaadf00d;
err = qemu_strtosz(str, NULL, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 12345);
str = "9007199254740991"; /* 2^53-1 */
+ endptr = str;
+ res = 0xbaadf00d;
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 */
+ endptr = str;
+ res = 0xbaadf00d;
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 */
+ endptr = str;
+ res = 0xbaadf00d;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 0x20000000000001);
g_assert(endptr == str + 16);
str = "18446744073709549568"; /* 0xfffffffffffff800 (53 msbs set) */
+ endptr = str;
+ res = 0xbaadf00d;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 0xfffffffffffff800);
g_assert(endptr == str + 20);
str = "18446744073709550591"; /* 0xfffffffffffffbff */
+ endptr = str;
+ res = 0xbaadf00d;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 0xfffffffffffffbff);
g_assert(endptr == str + 20);
str = "18446744073709551615"; /* 0xffffffffffffffff */
+ endptr = str;
+ res = 0xbaadf00d;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 0xffffffffffffffff);
@@ -2020,21 +2039,27 @@ static void test_qemu_strtosz_hex(void)
const char *str;
const char *endptr;
int err;
- uint64_t res = 0xbaadf00d;
+ uint64_t res;
str = "0x0";
+ endptr = str;
+ res = 0xbaadf00d;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 0);
g_assert(endptr == str + 3);
str = "0xab";
+ endptr = str;
+ res = 0xbaadf00d;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 171);
g_assert(endptr == str + 4);
str = "0xae";
+ endptr = str;
+ res = 0xbaadf00d;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 174);
@@ -2053,44 +2078,60 @@ static void test_qemu_strtosz_units(void)
const char *e = "1E";
int err;
const char *endptr;
- uint64_t res = 0xbaadf00d;
+ uint64_t res;
/* default is M */
+ endptr = NULL;
+ res = 0xbaadf00d;
err = qemu_strtosz_MiB(none, &endptr, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, MiB);
g_assert(endptr == none + 1);
+ endptr = NULL;
+ res = 0xbaadf00d;
err = qemu_strtosz(b, &endptr, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 1);
g_assert(endptr == b + 2);
+ endptr = NULL;
+ res = 0xbaadf00d;
err = qemu_strtosz(k, &endptr, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, KiB);
g_assert(endptr == k + 2);
+ endptr = NULL;
+ res = 0xbaadf00d;
err = qemu_strtosz(m, &endptr, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, MiB);
g_assert(endptr == m + 2);
+ endptr = NULL;
+ res = 0xbaadf00d;
err = qemu_strtosz(g, &endptr, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, GiB);
g_assert(endptr == g + 2);
+ endptr = NULL;
+ res = 0xbaadf00d;
err = qemu_strtosz(t, &endptr, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, TiB);
g_assert(endptr == t + 2);
+ endptr = NULL;
+ res = 0xbaadf00d;
err = qemu_strtosz(p, &endptr, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, PiB);
g_assert(endptr == p + 2);
+ endptr = NULL;
+ res = 0xbaadf00d;
err = qemu_strtosz(e, &endptr, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, EiB);
@@ -2102,9 +2143,11 @@ static void test_qemu_strtosz_float(void)
const char *str;
int err;
const char *endptr;
- uint64_t res = 0xbaadf00d;
+ uint64_t res;
str = "0.5E";
+ endptr = str;
+ res = 0xbaadf00d;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, EiB / 2);
@@ -2112,6 +2155,8 @@ static void test_qemu_strtosz_float(void)
/* For convenience, a fraction of 0 is tolerated even on bytes */
str = "1.0B";
+ endptr = str;
+ res = 0xbaadf00d;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 1);
@@ -2119,6 +2164,8 @@ static void test_qemu_strtosz_float(void)
/* An empty fraction is tolerated */
str = "1.k";
+ endptr = str;
+ res = 0xbaadf00d;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 1024);
@@ -2126,6 +2173,8 @@ static void test_qemu_strtosz_float(void)
/* For convenience, we permit values that are not byte-exact */
str = "12.345M";
+ endptr = str;
+ res = 0xbaadf00d;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, (uint64_t) (12.345 * MiB + 0.5));
@@ -2140,67 +2189,91 @@ static void test_qemu_strtosz_invalid(void)
uint64_t res = 0xbaadf00d;
str = "";
+ endptr = NULL;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, -EINVAL);
+ g_assert_cmpint(res, ==, 0xbaadf00d);
g_assert(endptr == str);
str = " \t ";
+ endptr = NULL;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, -EINVAL);
+ g_assert_cmpint(res, ==, 0xbaadf00d);
g_assert(endptr == str);
str = "crap";
+ endptr = NULL;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, -EINVAL);
+ g_assert_cmpint(res, ==, 0xbaadf00d);
g_assert(endptr == str);
str = "inf";
+ endptr = NULL;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, -EINVAL);
+ g_assert_cmpint(res, ==, 0xbaadf00d);
g_assert(endptr == str);
str = "NaN";
+ endptr = NULL;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, -EINVAL);
+ g_assert_cmpint(res, ==, 0xbaadf00d);
g_assert(endptr == str);
/* Fractional values require scale larger than bytes */
str = "1.1B";
+ endptr = NULL;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, -EINVAL);
+ g_assert_cmpint(res, ==, 0xbaadf00d);
g_assert(endptr == str);
str = "1.1";
+ endptr = NULL;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, -EINVAL);
+ g_assert_cmpint(res, ==, 0xbaadf00d);
g_assert(endptr == str);
/* No floating point exponents */
str = "1.5e1k";
+ endptr = NULL;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, -EINVAL);
+ g_assert_cmpint(res, ==, 0xbaadf00d);
g_assert(endptr == str);
str = "1.5E+0k";
+ endptr = NULL;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, -EINVAL);
+ g_assert_cmpint(res, ==, 0xbaadf00d);
g_assert(endptr == str);
/* No hex fractions */
str = "0x1.8k";
+ endptr = NULL;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, -EINVAL);
+ g_assert_cmpint(res, ==, 0xbaadf00d);
g_assert(endptr == str);
/* No negative values */
str = "-0";
+ endptr = NULL;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, -EINVAL);
+ g_assert_cmpint(res, ==, 0xbaadf00d);
g_assert(endptr == str);
str = "-1";
+ endptr = NULL;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, -EINVAL);
+ g_assert_cmpint(res, ==, 0xbaadf00d);
g_assert(endptr == str);
}
@@ -2209,48 +2282,72 @@ static void test_qemu_strtosz_trailing(void)
const char *str;
const char *endptr;
int err;
- uint64_t res = 0xbaadf00d;
+ uint64_t res;
str = "123xxx";
+ endptr = NULL;
+ res = 0xbaadf00d;
err = qemu_strtosz_MiB(str, &endptr, &res);
+ g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 123 * MiB);
g_assert(endptr == str + 3);
+ res = 0xbaadf00d;
err = qemu_strtosz(str, NULL, &res);
g_assert_cmpint(err, ==, -EINVAL);
+ g_assert_cmpint(res, ==, 0xbaadf00d);
str = "1kiB";
+ endptr = NULL;
+ res = 0xbaadf00d;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 1024);
g_assert(endptr == str + 2);
+ res = 0xbaadf00d;
err = qemu_strtosz(str, NULL, &res);
g_assert_cmpint(err, ==, -EINVAL);
+ g_assert_cmpint(res, ==, 0xbaadf00d);
str = "0x";
+ endptr = NULL;
+ res = 0xbaadf00d;
err = qemu_strtosz(str, &endptr, &res);
+ g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 0);
g_assert(endptr == str + 1);
+ res = 0xbaadf00d;
err = qemu_strtosz(str, NULL, &res);
g_assert_cmpint(err, ==, -EINVAL);
+ g_assert_cmpint(res, ==, 0xbaadf00d);
str = "0.NaN";
+ endptr = NULL;
+ res = 0xbaadf00d;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, 0);
+ g_assert_cmpint(res, ==, 0);
g_assert(endptr == str + 2);
+ res = 0xbaadf00d;
err = qemu_strtosz(str, NULL, &res);
g_assert_cmpint(err, ==, -EINVAL);
+ g_assert_cmpint(res, ==, 0xbaadf00d);
str = "123-45";
+ endptr = NULL;
+ res = 0xbaadf00d;
err = qemu_strtosz(str, &endptr, &res);
+ g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 123);
g_assert(endptr == str + 3);
+ res = 0xbaadf00d;
err = qemu_strtosz(str, NULL, &res);
g_assert_cmpint(err, ==, -EINVAL);
+ g_assert_cmpint(res, ==, 0xbaadf00d);
}
static void test_qemu_strtosz_erange(void)
@@ -2261,13 +2358,17 @@ static void test_qemu_strtosz_erange(void)
uint64_t res = 0xbaadf00d;
str = "18446744073709551616"; /* 2^64; see strtosz_simple for 2^64-1 */
+ endptr = NULL;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, -ERANGE);
+ g_assert_cmpint(res, ==, 0xbaadf00d);
g_assert(endptr == str + 20);
str = "20E";
+ endptr = NULL;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, -ERANGE);
+ g_assert_cmpint(res, ==, 0xbaadf00d);
g_assert(endptr == str + 3);
}
@@ -2276,15 +2377,19 @@ static void test_qemu_strtosz_metric(void)
const char *str;
int err;
const char *endptr;
- uint64_t res = 0xbaadf00d;
+ uint64_t res;
str = "12345k";
+ endptr = str;
+ res = 0xbaadf00d;
err = qemu_strtosz_metric(str, &endptr, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 12345000);
g_assert(endptr == str + 6);
str = "12.345M";
+ endptr = str;
+ res = 0xbaadf00d;
err = qemu_strtosz_metric(str, &endptr, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 12345000);
diff --git a/util/cutils.c b/util/cutils.c
index c442882b88..b425ed6570 100644
--- a/util/cutils.c
+++ b/util/cutils.c
@@ -362,7 +362,6 @@ static int do_strtosz(const char *nptr, const char **end,
}
}
- *result = val;
retval = 0;
out:
@@ -371,6 +370,9 @@ out:
} else if (*endptr) {
retval = -EINVAL;
}
+ if (retval == 0) {
+ *result = val;
+ }
return retval;
}
--
2.20.1
- [PATCH v1 03/14] docs/devel: expand style section of memory management, (continued)
- [PATCH v1 03/14] docs/devel: expand style section of memory management, Alex Bennée, 2021/03/20
- [PATCH v1 07/14] semihosting/arm-compat-semi: don't use SET_ARG to report SYS_HEAPINFO, Alex Bennée, 2021/03/20
- [PATCH v1 11/14] configure: Don't use the __atomic_*_16 functions for testing 128-bit support, Alex Bennée, 2021/03/20
- [PATCH v1 10/14] gitlab-ci.yml: Merge the trace-backend testing into other jobs, Alex Bennée, 2021/03/20
- [PATCH v1 06/14] semihosting/arm-compat-semi: unify GET/SET_ARG helpers, Alex Bennée, 2021/03/20
- [PATCH v1 09/14] tests/tcg: add HeapInfo checking to semihosting test, Alex Bennée, 2021/03/20
- [PATCH v1 12/14] cirrus.yml: Update the FreeBSD task to version 12.2, Alex Bennée, 2021/03/20
- [PATCH v1 14/14] utils: Work around mingw strto*l bug with 0x, Alex Bennée, 2021/03/20
- [PATCH v1 13/14] utils: Tighter tests for qemu_strtosz,
Alex Bennée <=
- Re: [PATCH for 6.0 v1 00/14] fixes for rc1 (kernel-doc, semihosting, testing), no-reply, 2021/03/20