aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorEric Blake <eblake@redhat.com>2023-05-22 14:04:41 -0500
committerEric Blake <eblake@redhat.com>2023-06-02 12:29:27 -0500
commit42cc08d13ab8e68f76882b216da0b28d06f29e11 (patch)
tree0597195d11f544191db2012599eff6e969e72c6c /tests
parentc25b1683443c6d658a82dc1c5587fdb0ae81663c (diff)
cutils: Improve qemu_strtosz handling of fractions
We have several limitations and bugs worth fixing; they are inter-related enough that it is not worth splitting this patch into smaller pieces: * ".5k" should work to specify 512, just as "0.5k" does * "1.9999k" and "1." + "9"*50 + "k" should both produce the same result of 2048 after rounding * "1." + "0"*350 + "1B" should not be treated the same as "1.0B"; underflow in the fraction should not be lost * "7.99e99" and "7.99e999" look similar, but our code was doing a read-out-of-bounds on the latter because it was not expecting ERANGE due to overflow. While we document that scientific notation is not supported, and the previous patch actually fixed qemu_strtod_finite() to no longer return ERANGE overflows, it is easier to pre-filter than to try and determine after the fact if strtod() consumed more than we wanted. Note that this is a low-level semantic change (when endptr is not NULL, we can now successfully parse with a scale of 'E' and then report trailing junk, instead of failing outright with EINVAL); but an earlier commit already argued that this is not a high-level semantic change since the only caller passing in a non-NULL endptr also checks that the tail is whitespace-only. Fixes: https://gitlab.com/qemu-project/qemu/-/issues/1629 Fixes: cf923b78 ("utils: Improve qemu_strtosz() to have 64 bits of precision", 6.0.0) Fixes: 7625a1ed ("utils: Use fixed-point arithmetic in qemu_strtosz", 6.0.0) Signed-off-by: Eric Blake <eblake@redhat.com> Reviewed-by: Hanna Czenczek <hreitz@redhat.com> Message-Id: <20230522190441.64278-20-eblake@redhat.com> [eblake: tweak function comment for accuracy]
Diffstat (limited to 'tests')
-rw-r--r--tests/unit/test-cutils.c50
1 files changed, 19 insertions, 31 deletions
diff --git a/tests/unit/test-cutils.c b/tests/unit/test-cutils.c
index 1ee410fae4..227acc5995 100644
--- a/tests/unit/test-cutils.c
+++ b/tests/unit/test-cutils.c
@@ -3408,19 +3408,18 @@ static void test_qemu_strtosz_float(void)
/* An empty fraction tail is tolerated */
do_strtosz("1.k", 0, 1024, 3);
- /* FIXME An empty fraction head should be tolerated */
- do_strtosz(" .5k", -EINVAL /* FIXME 0 */, 0 /* FIXME 512 */,
- 0 /* FIXME 4 */);
+ /* An empty fraction head is tolerated */
+ do_strtosz(" .5k", 0, 512, 4);
/* For convenience, we permit values that are not byte-exact */
do_strtosz("12.345M", 0, (uint64_t) (12.345 * MiB + 0.5), 7);
- /* FIXME Fraction tail should round correctly */
+ /* Fraction tail can round up */
do_strtosz("1.9999k", 0, 2048, 7);
do_strtosz("1.9999999999999999999999999999999999999999999999999999k", 0,
- 1024 /* FIXME 2048 */, 55);
+ 2048, 55);
- /* FIXME ERANGE underflow in the fraction tail should not matter for 'k' */
+ /* ERANGE underflow in the fraction tail does not matter for 'k' */
do_strtosz("1."
"00000000000000000000000000000000000000000000000000"
"00000000000000000000000000000000000000000000000000"
@@ -3429,7 +3428,7 @@ static void test_qemu_strtosz_float(void)
"00000000000000000000000000000000000000000000000000"
"00000000000000000000000000000000000000000000000000"
"00000000000000000000000000000000000000000000000000"
- "1k", 0, 1 /* FIXME 1024 */, 354);
+ "1k", 0, 1024, 354);
}
static void test_qemu_strtosz_invalid(void)
@@ -3453,10 +3452,9 @@ static void test_qemu_strtosz_invalid(void)
do_strtosz("1.1B", -EINVAL, 0, 0);
do_strtosz("1.1", -EINVAL, 0, 0);
- /* FIXME underflow in the fraction tail should matter for 'B' */
+ /* 'B' cannot have any nonzero fraction, even with rounding or underflow */
do_strtosz("1.00001B", -EINVAL, 0, 0);
- do_strtosz("1.00000000000000000001B", 0 /* FIXME -EINVAL */,
- 1 /* FIXME 0 */, 23 /* FIXME 0 */);
+ do_strtosz("1.00000000000000000001B", -EINVAL, 0, 0);
do_strtosz("1."
"00000000000000000000000000000000000000000000000000"
"00000000000000000000000000000000000000000000000000"
@@ -3465,8 +3463,7 @@ static void test_qemu_strtosz_invalid(void)
"00000000000000000000000000000000000000000000000000"
"00000000000000000000000000000000000000000000000000"
"00000000000000000000000000000000000000000000000000"
- "1B", 0 /* FIXME -EINVAL */, 1 /* FIXME 0 */,
- 354 /* FIXME 0 */);
+ "1B", -EINVAL, 0, 0);
/* No hex fractions */
do_strtosz("0x1.8k", -EINVAL, 0, 0);
@@ -3512,28 +3509,20 @@ static void test_qemu_strtosz_trailing(void)
do_strtosz_full("123-45", qemu_strtosz, 0, 123, 3, -EINVAL, 0);
do_strtosz_full(" 123 - 45", qemu_strtosz, 0, 123, 4, -EINVAL, 0);
- /* FIXME should stop parse after 'e'. No floating point exponents */
- do_strtosz_full("1.5e1k", qemu_strtosz, -EINVAL /* FIXME 0 */,
- 0 /* FIXME EiB * 1.5 */, 0 /* FIXME 4 */,
- -EINVAL, 0);
- do_strtosz_full("1.5E+0k", qemu_strtosz, -EINVAL /* FIXME 0 */,
- 0 /* FIXME EiB * 1.5 */, 0 /* FIXME 4 */,
- -EINVAL, 0);
-
- /* FIXME overflow in fraction is still buggy */
- do_strtosz_full("1.5E999", qemu_strtosz, 0, 1 /* FIXME EiB * 1.5 */,
- 2 /* FIXME 4 */, -EINVAL, 0);
+ /* Parse stops at 'e', which is not a floating point exponent */
+ do_strtosz_full("1.5e1k", qemu_strtosz, 0, EiB * 1.5, 4, -EINVAL, 0);
+ do_strtosz_full("1.5E+0k", qemu_strtosz, 0, EiB * 1.5, 4, -EINVAL, 0);
+ do_strtosz_full("1.5E999", qemu_strtosz, 0, EiB * 1.5, 4, -EINVAL, 0);
}
static void test_qemu_strtosz_erange(void)
{
- /* FIXME negative values fit better as ERANGE */
+ /* no negative values */
do_strtosz(" -0", -ERANGE, 0, 3);
do_strtosz("-1", -ERANGE, 0, 2);
do_strtosz_full("-2M", qemu_strtosz, -ERANGE, 0, 2, -EINVAL, 0);
- do_strtosz(" -.0", -EINVAL /* FIXME -ERANGE */, 0, 0 /* FIXME 4 */);
- do_strtosz_full("-.1k", qemu_strtosz, -EINVAL /* FIXME -ERANGE */, 0,
- 0 /* FIXME 3 */, -EINVAL, 0);
+ do_strtosz(" -.0", -ERANGE, 0, 4);
+ do_strtosz_full("-.1k", qemu_strtosz, -ERANGE, 0, 3, -EINVAL, 0);
do_strtosz_full(" -."
"00000000000000000000000000000000000000000000000000"
"00000000000000000000000000000000000000000000000000"
@@ -3542,17 +3531,16 @@ static void test_qemu_strtosz_erange(void)
"00000000000000000000000000000000000000000000000000"
"00000000000000000000000000000000000000000000000000"
"00000000000000000000000000000000000000000000000000"
- "1M", qemu_strtosz, -EINVAL /* FIXME -ERANGE */, 0,
- 0 /* FIXME 354 */, -EINVAL, 0);
+ "1M", qemu_strtosz, -ERANGE, 0, 354, -EINVAL, 0);
/* 2^64; see strtosz_simple for 2^64-1 */
do_strtosz("18446744073709551616", -ERANGE, 0, 20);
do_strtosz("20E", -ERANGE, 0, 3);
- /* FIXME Fraction tail can cause ERANGE overflow */
+ /* Fraction tail can cause ERANGE overflow */
do_strtosz("15.9999999999999999999999999999999999999999999999999999E",
- 0 /* FIXME -ERANGE */, 15ULL * EiB /* FIXME 0 */, 56);
+ -ERANGE, 0, 56);
/* EINVAL has priority over ERANGE */
do_strtosz_full("100000Pjunk", qemu_strtosz, -ERANGE, 0, 7, -EINVAL, 0);