aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Hildenbrand <david@redhat.com>2018-11-21 17:44:14 +0100
committerMarkus Armbruster <armbru@redhat.com>2018-12-13 19:10:06 +0100
commitaf02f4c5179675ad4e26b17ba26694a8fcde17fa (patch)
tree7b316a4e89c962284f479f604f4b2515b4cc4f97
parentca28f5481607e5c59481e70e429f5dd23662cb69 (diff)
downloadqemu-af02f4c5179675ad4e26b17ba26694a8fcde17fa.zip
qemu-af02f4c5179675ad4e26b17ba26694a8fcde17fa.tar.gz
qemu-af02f4c5179675ad4e26b17ba26694a8fcde17fa.tar.bz2
cutils: Fix qemu_strtosz() & friends to reject non-finite sizes
qemu_strtosz() & friends reject NaNs, but happily accept infinities. They shouldn't. Fix that. The fix makes use of qemu_strtod_finite(). To avoid ugly casts, change the @end parameter of qemu_strtosz() & friends from char ** to const char **. Also, add two test cases, testing that "inf" and "NaN" are properly rejected. While at it, also fixup the function documentation. Reviewed-by: Eric Blake <eblake@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: David Hildenbrand <david@redhat.com> Message-Id: <20181121164421.20780-3-david@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
-rw-r--r--include/qemu/cutils.h6
-rw-r--r--monitor.c2
-rw-r--r--tests/test-cutils.c24
-rw-r--r--util/cutils.c18
4 files changed, 29 insertions, 21 deletions
diff --git a/include/qemu/cutils.h b/include/qemu/cutils.h
index 756b41c..d2dad30 100644
--- a/include/qemu/cutils.h
+++ b/include/qemu/cutils.h
@@ -153,9 +153,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, 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);
+int qemu_strtosz(const char *nptr, const char **end, uint64_t *result);
+int qemu_strtosz_MiB(const char *nptr, const char **end, uint64_t *result);
+int qemu_strtosz_metric(const char *nptr, const char **end, uint64_t *result);
/* used to print char* safely */
#define STR_OR_NULL(str) ((str) ? (str) : "null")
diff --git a/monitor.c b/monitor.c
index 6e81b09..cf9cece 100644
--- a/monitor.c
+++ b/monitor.c
@@ -3232,7 +3232,7 @@ static QDict *monitor_parse_arguments(Monitor *mon,
{
int ret;
uint64_t val;
- char *end;
+ const char *end;
while (qemu_isspace(*p)) {
p++;
diff --git a/tests/test-cutils.c b/tests/test-cutils.c
index d85c3e0..1aa8351 100644
--- a/tests/test-cutils.c
+++ b/tests/test-cutils.c
@@ -1950,7 +1950,7 @@ static void test_qemu_strtou64_full_max(void)
static void test_qemu_strtosz_simple(void)
{
const char *str;
- char *endptr = NULL;
+ const char *endptr;
int err;
uint64_t res = 0xbaadf00d;
@@ -2017,7 +2017,7 @@ static void test_qemu_strtosz_units(void)
const char *p = "1P";
const char *e = "1E";
int err;
- char *endptr = NULL;
+ const char *endptr;
uint64_t res = 0xbaadf00d;
/* default is M */
@@ -2066,7 +2066,7 @@ static void test_qemu_strtosz_float(void)
{
const char *str = "12.345M";
int err;
- char *endptr = NULL;
+ const char *endptr;
uint64_t res = 0xbaadf00d;
err = qemu_strtosz(str, &endptr, &res);
@@ -2078,7 +2078,7 @@ static void test_qemu_strtosz_float(void)
static void test_qemu_strtosz_invalid(void)
{
const char *str;
- char *endptr = NULL;
+ const char *endptr;
int err;
uint64_t res = 0xbaadf00d;
@@ -2096,12 +2096,22 @@ static void test_qemu_strtosz_invalid(void)
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, -EINVAL);
g_assert(endptr == str);
+
+ str = "inf";
+ err = qemu_strtosz(str, &endptr, &res);
+ g_assert_cmpint(err, ==, -EINVAL);
+ g_assert(endptr == str);
+
+ str = "NaN";
+ err = qemu_strtosz(str, &endptr, &res);
+ g_assert_cmpint(err, ==, -EINVAL);
+ g_assert(endptr == str);
}
static void test_qemu_strtosz_trailing(void)
{
const char *str;
- char *endptr = NULL;
+ const char *endptr;
int err;
uint64_t res = 0xbaadf00d;
@@ -2126,7 +2136,7 @@ static void test_qemu_strtosz_trailing(void)
static void test_qemu_strtosz_erange(void)
{
const char *str;
- char *endptr = NULL;
+ const char *endptr;
int err;
uint64_t res = 0xbaadf00d;
@@ -2160,7 +2170,7 @@ static void test_qemu_strtosz_metric(void)
{
const char *str = "12345k";
int err;
- char *endptr = NULL;
+ const char *endptr;
uint64_t res = 0xbaadf00d;
err = qemu_strtosz_metric(str, &endptr, &res);
diff --git a/util/cutils.c b/util/cutils.c
index ec0a401..e098deb 100644
--- a/util/cutils.c
+++ b/util/cutils.c
@@ -203,23 +203,21 @@ static int64_t suffix_mul(char suffix, int64_t unit)
/*
* Convert string to bytes, allowing either B/b for bytes, K/k for KB,
* M/m for MB, G/g for GB or T/t for TB. End pointer will be returned
- * in *end, if not NULL. Return -ERANGE on overflow, Return -EINVAL on
+ * in *end, if not NULL. Return -ERANGE on overflow, and -EINVAL on
* other error.
*/
-static int do_strtosz(const char *nptr, char **end,
+static int do_strtosz(const char *nptr, const char **end,
const char default_suffix, int64_t unit,
uint64_t *result)
{
int retval;
- char *endptr;
+ const char *endptr;
unsigned char c;
int mul_required = 0;
double val, mul, integral, fraction;
- errno = 0;
- val = strtod(nptr, &endptr);
- if (isnan(val) || endptr == nptr || errno != 0) {
- retval = -EINVAL;
+ retval = qemu_strtod_finite(nptr, &endptr, &val);
+ if (retval) {
goto out;
}
fraction = modf(val, &integral);
@@ -259,17 +257,17 @@ out:
return retval;
}
-int qemu_strtosz(const char *nptr, char **end, uint64_t *result)
+int qemu_strtosz(const char *nptr, const char **end, uint64_t *result)
{
return do_strtosz(nptr, end, 'B', 1024, result);
}
-int qemu_strtosz_MiB(const char *nptr, char **end, uint64_t *result)
+int qemu_strtosz_MiB(const char *nptr, const char **end, uint64_t *result)
{
return do_strtosz(nptr, end, 'M', 1024, result);
}
-int qemu_strtosz_metric(const char *nptr, char **end, uint64_t *result)
+int qemu_strtosz_metric(const char *nptr, const char **end, uint64_t *result)
{
return do_strtosz(nptr, end, 'B', 1000, result);
}