cutils: Use parse_uint in qemu_strtosz for negative rejection

Rather than open-coding two different ways to check for an unwanted
negative sign, reuse the same code in both functions.  That way, if we
decide down the road to accept "-0" instead of rejecting it, we have
fewer places to change.  Also, it means we now get ERANGE instead of
EINVAL for negative values in qemu_strtosz, which is reasonable for
what it represents.  This in turn changes the expected output of a
couple of iotests.

The change is not quite complete: negative fractional scaled values
can trip us up.  This will be fixed in a later patch addressing other
issues with fractional scaled values.

Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Hanna Czenczek <hreitz@redhat.com>
Message-Id: <20230522190441.64278-18-eblake@redhat.com>
This commit is contained in:
Eric Blake 2023-05-22 14:04:39 -05:00
parent 3c5f246798
commit b87ac96651
5 changed files with 9 additions and 19 deletions

View file

@ -92,13 +92,10 @@ Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off comp
== 3. Invalid sizes ==
qemu-img create -f qcow2 TEST_DIR/t.qcow2 -- -1024
qemu-img: Invalid image size specified. You may use k, M, G, T, P or E suffixes for
qemu-img: kilobytes, megabytes, gigabytes, terabytes, petabytes and exabytes.
qemu-img: Invalid image size specified. Must be between 0 and 9223372036854775807.
qemu-img create -f qcow2 -o size=-1024 TEST_DIR/t.qcow2
qemu-img: TEST_DIR/t.qcow2: Parameter 'size' expects a non-negative number below 2^64
Optional suffix k, M, G, T, P or E means kilo-, mega-, giga-, tera-, peta-
and exabytes, respectively.
qemu-img: TEST_DIR/t.qcow2: Value '-1024' is out of range for parameter 'size'
qemu-img create -f qcow2 TEST_DIR/t.qcow2 -- -1k
qemu-img: Invalid image size specified. You may use k, M, G, T, P or E suffixes for

View file

@ -13,8 +13,7 @@ qemu-img: Invalid option list: ,
qemu-img: Invalid parameter 'snapshot.foo'
qemu-img: Failed in parsing snapshot param 'snapshot.foo=bar'
qemu-img: --output must be used with human or json as argument.
qemu-img: Invalid image size specified. You may use k, M, G, T, P or E suffixes for
qemu-img: kilobytes, megabytes, gigabytes, terabytes, petabytes and exabytes.
qemu-img: Invalid image size specified. Must be between 0 and 9223372036854775807.
qemu-img: Unknown file format 'foo'
== Size calculation for a new file (human) ==

View file

@ -13,8 +13,7 @@ qemu-img: Invalid option list: ,
qemu-img: Invalid parameter 'snapshot.foo'
qemu-img: Failed in parsing snapshot param 'snapshot.foo=bar'
qemu-img: --output must be used with human or json as argument.
qemu-img: Invalid image size specified. You may use k, M, G, T, P or E suffixes for
qemu-img: kilobytes, megabytes, gigabytes, terabytes, petabytes and exabytes.
qemu-img: Invalid image size specified. Must be between 0 and 9223372036854775807.
qemu-img: Unknown file format 'foo'
== Size calculation for a new file (human) ==

View file

@ -3519,10 +3519,9 @@ static void test_qemu_strtosz_trailing(void)
static void test_qemu_strtosz_erange(void)
{
/* FIXME negative values fit better as ERANGE */
do_strtosz(" -0", -EINVAL /* FIXME -ERANGE */, 0, 0 /* FIXME 3 */);
do_strtosz("-1", -EINVAL /* FIXME -ERANGE */, 0, 0 /* FIXME 2 */);
do_strtosz_full("-2M", qemu_strtosz, -EINVAL /* FIXME -ERANGE */, 0,
0 /* FIXME 2 */, -EINVAL, 0);
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);

View file

@ -201,6 +201,7 @@ static int64_t suffix_mul(char suffix, int64_t unit)
* - hex with scaling suffix, such as 0x20M
* - octal, such as 08
* - fractional hex, such as 0x1.8
* - negative values, including -0
* - floating point exponents, such as 1e3
*
* The end pointer will be returned in *end, if not NULL. If there is
@ -226,15 +227,10 @@ static int do_strtosz(const char *nptr, const char **end,
int64_t mul;
/* Parse integral portion as decimal. */
retval = qemu_strtou64(nptr, &endptr, 10, &val);
retval = parse_uint(nptr, &endptr, 10, &val);
if (retval) {
goto out;
}
if (memchr(nptr, '-', endptr - nptr) != NULL) {
endptr = nptr;
retval = -EINVAL;
goto out;
}
if (val == 0 && (*endptr == 'x' || *endptr == 'X')) {
/* Input looks like hex; reparse, and insist on no fraction or suffix. */
retval = qemu_strtou64(nptr, &endptr, 16, &val);