From nobody Thu Nov 6 19:29:26 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1542818787543760.0350371361706; Wed, 21 Nov 2018 08:46:27 -0800 (PST) Received: from localhost ([::1]:40174 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gPVds-0008No-1Y for importer@patchew.org; Wed, 21 Nov 2018 11:46:20 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51635) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gPVc7-0007QG-3S for qemu-devel@nongnu.org; Wed, 21 Nov 2018 11:44:32 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gPVc6-0006aB-4t for qemu-devel@nongnu.org; Wed, 21 Nov 2018 11:44:31 -0500 Received: from mx1.redhat.com ([209.132.183.28]:41886) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gPVc5-0006ZW-Ty for qemu-devel@nongnu.org; Wed, 21 Nov 2018 11:44:30 -0500 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 454802D7F7; Wed, 21 Nov 2018 16:44:29 +0000 (UTC) Received: from t460s.redhat.com (ovpn-116-177.ams2.redhat.com [10.36.116.177]) by smtp.corp.redhat.com (Postfix) with ESMTP id D342C5C241; Wed, 21 Nov 2018 16:44:27 +0000 (UTC) From: David Hildenbrand To: qemu-devel@nongnu.org Date: Wed, 21 Nov 2018 17:44:14 +0100 Message-Id: <20181121164421.20780-3-david@redhat.com> In-Reply-To: <20181121164421.20780-1-david@redhat.com> References: <20181121164421.20780-1-david@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Wed, 21 Nov 2018 16:44:29 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v3 for-4.0 2/9] cutils: Fix qemu_strtosz() & friends to reject non-finite sizes X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Paolo Bonzini , David Hildenbrand , Markus Armbruster , Michael Roth Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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 Reviewed-by: Markus Armbruster Signed-off-by: David Hildenbrand --- include/qemu/cutils.h | 6 +++--- monitor.c | 2 +- tests/test-cutils.c | 24 +++++++++++++++++------- util/cutils.c | 18 ++++++++---------- 4 files changed, 29 insertions(+), 21 deletions(-) diff --git a/include/qemu/cutils.h b/include/qemu/cutils.h index 756b41c193..d2dad3057c 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); =20 -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 *resu= lt); =20 /* used to print char* safely */ #define STR_OR_NULL(str) ((str) ? (str) : "null") diff --git a/monitor.c b/monitor.c index d39390c2f2..ee9893c785 100644 --- a/monitor.c +++ b/monitor.c @@ -3231,7 +3231,7 @@ static QDict *monitor_parse_arguments(Monitor *mon, { int ret; uint64_t val; - char *end; + const char *end; =20 while (qemu_isspace(*p)) { p++; diff --git a/tests/test-cutils.c b/tests/test-cutils.c index d85c3e0f6d..1aa8351520 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 =3D NULL; + const char *endptr; int err; uint64_t res =3D 0xbaadf00d; =20 @@ -2017,7 +2017,7 @@ static void test_qemu_strtosz_units(void) const char *p =3D "1P"; const char *e =3D "1E"; int err; - char *endptr =3D NULL; + const char *endptr; uint64_t res =3D 0xbaadf00d; =20 /* default is M */ @@ -2066,7 +2066,7 @@ static void test_qemu_strtosz_float(void) { const char *str =3D "12.345M"; int err; - char *endptr =3D NULL; + const char *endptr; uint64_t res =3D 0xbaadf00d; =20 err =3D 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 =3D NULL; + const char *endptr; int err; uint64_t res =3D 0xbaadf00d; =20 @@ -2096,12 +2096,22 @@ static void test_qemu_strtosz_invalid(void) err =3D qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, =3D=3D, -EINVAL); g_assert(endptr =3D=3D str); + + str =3D "inf"; + err =3D qemu_strtosz(str, &endptr, &res); + g_assert_cmpint(err, =3D=3D, -EINVAL); + g_assert(endptr =3D=3D str); + + str =3D "NaN"; + err =3D qemu_strtosz(str, &endptr, &res); + g_assert_cmpint(err, =3D=3D, -EINVAL); + g_assert(endptr =3D=3D str); } =20 static void test_qemu_strtosz_trailing(void) { const char *str; - char *endptr =3D NULL; + const char *endptr; int err; uint64_t res =3D 0xbaadf00d; =20 @@ -2126,7 +2136,7 @@ static void test_qemu_strtosz_trailing(void) static void test_qemu_strtosz_erange(void) { const char *str; - char *endptr =3D NULL; + const char *endptr; int err; uint64_t res =3D 0xbaadf00d; =20 @@ -2160,7 +2170,7 @@ static void test_qemu_strtosz_metric(void) { const char *str =3D "12345k"; int err; - char *endptr =3D NULL; + const char *endptr; uint64_t res =3D 0xbaadf00d; =20 err =3D qemu_strtosz_metric(str, &endptr, &res); diff --git a/util/cutils.c b/util/cutils.c index 173407d2fd..91930d1bbe 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 =3D 0; double val, mul, integral, fraction; =20 - errno =3D 0; - val =3D strtod(nptr, &endptr); - if (isnan(val) || endptr =3D=3D nptr || errno !=3D 0) { - retval =3D -EINVAL; + retval =3D qemu_strtod_finite(nptr, &endptr, &val); + if (retval) { goto out; } fraction =3D modf(val, &integral); @@ -259,17 +257,17 @@ out: return retval; } =20 -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); } =20 -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); } =20 -int qemu_strtosz_metric(const char *nptr, char **end, uint64_t *result) +int qemu_strtosz_metric(const char *nptr, const char **end, uint64_t *resu= lt) { return do_strtosz(nptr, end, 'B', 1000, result); } --=20 2.17.2