From patchwork Mon May 8 20:03:33 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Blake X-Patchwork-Id: 13235000 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id AC466C77B7F for ; Mon, 8 May 2023 20:04:31 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pw75g-0006Gm-UC; Mon, 08 May 2023 16:04:12 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pw75N-0006EL-5U for qemu-devel@nongnu.org; Mon, 08 May 2023 16:03:54 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pw75I-0007Ip-5t for qemu-devel@nongnu.org; Mon, 08 May 2023 16:03:52 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1683576227; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=k0Pp2dtIvRWl+Mh+HawhUw+V8Kitx7mVtdgZA29ZO1s=; b=Uz6wx70LwWSvrBkjF9DtkJZfSy+qy5sW0rd/UMfKhNCm0Gp9X0I/6Q0+e1C2RM7qXqBbXp +hCl8XZE767s8i2RF1ajACEakn0ijfG5uQ5xEDWDfMSfx/md6QgXVJcPQQTHymmyJgqyJn QLQNOP4Cbm31y292b2D+2Pcb1XmBdP4= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-360-g9w5MoGjP7ibmLGUltR-qw-1; Mon, 08 May 2023 16:03:46 -0400 X-MC-Unique: g9w5MoGjP7ibmLGUltR-qw-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id EC2681006849 for ; Mon, 8 May 2023 20:03:45 +0000 (UTC) Received: from green.redhat.com (unknown [10.2.16.49]) by smtp.corp.redhat.com (Postfix) with ESMTP id 81F4F1121314; Mon, 8 May 2023 20:03:45 +0000 (UTC) From: Eric Blake To: qemu-devel@nongnu.org Cc: hreitz@redhat.com Subject: [PATCH 01/11] test-cutils: Avoid g_assert in unit tests Date: Mon, 8 May 2023 15:03:33 -0500 Message-Id: <20230508200343.791450-2-eblake@redhat.com> In-Reply-To: <20230508200343.791450-1-eblake@redhat.com> References: <20230508200343.791450-1-eblake@redhat.com> MIME-Version: 1.0 Content-type: text/plain X-Scanned-By: MIMEDefang 3.1 on 10.11.54.3 Received-SPF: pass client-ip=170.10.133.124; envelope-from=eblake@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org glib documentation[1] is clear: g_assert() should be avoided in unit tests because it is ineffective if G_DISABLE_ASSERT is defined; unit tests should stick to constructs based on g_assert_true() instead. Note that since commit 262a69f428, we intentionally state that you cannot define G_DISABLE_ASSERT that while building qemu; but our code can be copied to other projects without that restriction, so we should be consistent. For most of the replacements in this patch, using g_assert_cmpstr() would be a regression in quality - although it would helpfully display the string contents of both pointers on test failure, here, we really do care about pointer equality, not just string content equality. But when a NULL pointer is expected, g_assert_null works fine. [1] https://libsoup.org/glib/glib-Testing.html#g-assert Signed-off-by: Eric Blake --- tests/unit/test-cutils.c | 324 +++++++++++++++++++-------------------- 1 file changed, 162 insertions(+), 162 deletions(-) diff --git a/tests/unit/test-cutils.c b/tests/unit/test-cutils.c index 3c4f8754202..0202ac0d5b3 100644 --- a/tests/unit/test-cutils.c +++ b/tests/unit/test-cutils.c @@ -1,7 +1,7 @@ /* * cutils.c unit-tests * - * Copyright (C) 2013 Red Hat Inc. + * Copyright Red Hat * * Authors: * Eduardo Habkost @@ -40,7 +40,7 @@ static void test_parse_uint_null(void) g_assert_cmpint(r, ==, -EINVAL); g_assert_cmpint(i, ==, 0); - g_assert(endptr == NULL); + g_assert_null(endptr); } static void test_parse_uint_empty(void) @@ -55,7 +55,7 @@ static void test_parse_uint_empty(void) g_assert_cmpint(r, ==, -EINVAL); g_assert_cmpint(i, ==, 0); - g_assert(endptr == str); + g_assert_true(endptr == str); } static void test_parse_uint_whitespace(void) @@ -70,7 +70,7 @@ static void test_parse_uint_whitespace(void) g_assert_cmpint(r, ==, -EINVAL); g_assert_cmpint(i, ==, 0); - g_assert(endptr == str); + g_assert_true(endptr == str); } @@ -86,7 +86,7 @@ static void test_parse_uint_invalid(void) g_assert_cmpint(r, ==, -EINVAL); g_assert_cmpint(i, ==, 0); - g_assert(endptr == str); + g_assert_true(endptr == str); } @@ -102,7 +102,7 @@ static void test_parse_uint_trailing(void) g_assert_cmpint(r, ==, 0); g_assert_cmpint(i, ==, 123); - g_assert(endptr == str + 3); + g_assert_true(endptr == str + 3); } static void test_parse_uint_correct(void) @@ -117,7 +117,7 @@ static void test_parse_uint_correct(void) g_assert_cmpint(r, ==, 0); g_assert_cmpint(i, ==, 123); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); } static void test_parse_uint_octal(void) @@ -132,7 +132,7 @@ static void test_parse_uint_octal(void) g_assert_cmpint(r, ==, 0); g_assert_cmpint(i, ==, 0123); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); } static void test_parse_uint_decimal(void) @@ -147,7 +147,7 @@ static void test_parse_uint_decimal(void) g_assert_cmpint(r, ==, 0); g_assert_cmpint(i, ==, 123); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); } @@ -163,7 +163,7 @@ static void test_parse_uint_llong_max(void) g_assert_cmpint(r, ==, 0); g_assert_cmpint(i, ==, (unsigned long long)LLONG_MAX + 1); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); g_free(str); } @@ -180,7 +180,7 @@ static void test_parse_uint_overflow(void) g_assert_cmpint(r, ==, -ERANGE); g_assert_cmpint(i, ==, ULLONG_MAX); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); } static void test_parse_uint_negative(void) @@ -195,7 +195,7 @@ static void test_parse_uint_negative(void) g_assert_cmpint(r, ==, -ERANGE); g_assert_cmpint(i, ==, 0); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); } @@ -235,7 +235,7 @@ static void test_qemu_strtoi_correct(void) g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, 12345); - g_assert(endptr == str + 5); + g_assert_true(endptr == str + 5); } static void test_qemu_strtoi_null(void) @@ -248,7 +248,7 @@ static void test_qemu_strtoi_null(void) err = qemu_strtoi(NULL, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert(endptr == NULL); + g_assert_null(endptr); } static void test_qemu_strtoi_empty(void) @@ -262,7 +262,7 @@ static void test_qemu_strtoi_empty(void) err = qemu_strtoi(str, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert(endptr == str); + g_assert_true(endptr == str); } static void test_qemu_strtoi_whitespace(void) @@ -276,7 +276,7 @@ static void test_qemu_strtoi_whitespace(void) err = qemu_strtoi(str, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert(endptr == str); + g_assert_true(endptr == str); } static void test_qemu_strtoi_invalid(void) @@ -290,7 +290,7 @@ static void test_qemu_strtoi_invalid(void) err = qemu_strtoi(str, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert(endptr == str); + g_assert_true(endptr == str); } static void test_qemu_strtoi_trailing(void) @@ -305,7 +305,7 @@ static void test_qemu_strtoi_trailing(void) g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, 123); - g_assert(endptr == str + 3); + g_assert_true(endptr == str + 3); } static void test_qemu_strtoi_octal(void) @@ -320,7 +320,7 @@ static void test_qemu_strtoi_octal(void) g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, 0123); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); res = 999; endptr = &f; @@ -328,7 +328,7 @@ static void test_qemu_strtoi_octal(void) g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, 0123); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); } static void test_qemu_strtoi_decimal(void) @@ -343,7 +343,7 @@ static void test_qemu_strtoi_decimal(void) g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, 123); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); str = "123"; res = 999; @@ -352,7 +352,7 @@ static void test_qemu_strtoi_decimal(void) g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, 123); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); } static void test_qemu_strtoi_hex(void) @@ -367,7 +367,7 @@ static void test_qemu_strtoi_hex(void) g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, 0x123); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); str = "0x123"; res = 999; @@ -376,7 +376,7 @@ static void test_qemu_strtoi_hex(void) g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, 0x123); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); str = "0x"; res = 999; @@ -385,7 +385,7 @@ static void test_qemu_strtoi_hex(void) g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, 0); - g_assert(endptr == str + 1); + g_assert_true(endptr == str + 1); } static void test_qemu_strtoi_max(void) @@ -400,7 +400,7 @@ static void test_qemu_strtoi_max(void) g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, INT_MAX); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); g_free(str); } @@ -416,7 +416,7 @@ static void test_qemu_strtoi_overflow(void) g_assert_cmpint(err, ==, -ERANGE); g_assert_cmpint(res, ==, INT_MAX); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); g_free(str); } @@ -432,7 +432,7 @@ static void test_qemu_strtoi_underflow(void) g_assert_cmpint(err, ==, -ERANGE); g_assert_cmpint(res, ==, INT_MIN); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); g_free(str); } @@ -448,7 +448,7 @@ static void test_qemu_strtoi_negative(void) g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, -321); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); } static void test_qemu_strtoi_full_correct(void) @@ -473,7 +473,7 @@ static void test_qemu_strtoi_full_null(void) err = qemu_strtoi(NULL, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert(endptr == NULL); + g_assert_null(endptr); } static void test_qemu_strtoi_full_empty(void) @@ -535,7 +535,7 @@ static void test_qemu_strtoui_correct(void) g_assert_cmpint(err, ==, 0); g_assert_cmpuint(res, ==, 12345); - g_assert(endptr == str + 5); + g_assert_true(endptr == str + 5); } static void test_qemu_strtoui_null(void) @@ -548,7 +548,7 @@ static void test_qemu_strtoui_null(void) err = qemu_strtoui(NULL, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert(endptr == NULL); + g_assert_null(endptr); } static void test_qemu_strtoui_empty(void) @@ -562,7 +562,7 @@ static void test_qemu_strtoui_empty(void) err = qemu_strtoui(str, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert(endptr == str); + g_assert_true(endptr == str); } static void test_qemu_strtoui_whitespace(void) @@ -576,7 +576,7 @@ static void test_qemu_strtoui_whitespace(void) err = qemu_strtoui(str, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert(endptr == str); + g_assert_true(endptr == str); } static void test_qemu_strtoui_invalid(void) @@ -590,7 +590,7 @@ static void test_qemu_strtoui_invalid(void) err = qemu_strtoui(str, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert(endptr == str); + g_assert_true(endptr == str); } static void test_qemu_strtoui_trailing(void) @@ -605,7 +605,7 @@ static void test_qemu_strtoui_trailing(void) g_assert_cmpint(err, ==, 0); g_assert_cmpuint(res, ==, 123); - g_assert(endptr == str + 3); + g_assert_true(endptr == str + 3); } static void test_qemu_strtoui_octal(void) @@ -620,7 +620,7 @@ static void test_qemu_strtoui_octal(void) g_assert_cmpint(err, ==, 0); g_assert_cmpuint(res, ==, 0123); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); res = 999; endptr = &f; @@ -628,7 +628,7 @@ static void test_qemu_strtoui_octal(void) g_assert_cmpint(err, ==, 0); g_assert_cmpuint(res, ==, 0123); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); } static void test_qemu_strtoui_decimal(void) @@ -643,7 +643,7 @@ static void test_qemu_strtoui_decimal(void) g_assert_cmpint(err, ==, 0); g_assert_cmpuint(res, ==, 123); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); str = "123"; res = 999; @@ -652,7 +652,7 @@ static void test_qemu_strtoui_decimal(void) g_assert_cmpint(err, ==, 0); g_assert_cmpuint(res, ==, 123); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); } static void test_qemu_strtoui_hex(void) @@ -667,7 +667,7 @@ static void test_qemu_strtoui_hex(void) g_assert_cmpint(err, ==, 0); g_assert_cmphex(res, ==, 0x123); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); str = "0x123"; res = 999; @@ -676,7 +676,7 @@ static void test_qemu_strtoui_hex(void) g_assert_cmpint(err, ==, 0); g_assert_cmphex(res, ==, 0x123); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); str = "0x"; res = 999; @@ -685,7 +685,7 @@ static void test_qemu_strtoui_hex(void) g_assert_cmpint(err, ==, 0); g_assert_cmphex(res, ==, 0); - g_assert(endptr == str + 1); + g_assert_true(endptr == str + 1); } static void test_qemu_strtoui_max(void) @@ -700,7 +700,7 @@ static void test_qemu_strtoui_max(void) g_assert_cmpint(err, ==, 0); g_assert_cmphex(res, ==, UINT_MAX); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); g_free(str); } @@ -716,7 +716,7 @@ static void test_qemu_strtoui_overflow(void) g_assert_cmpint(err, ==, -ERANGE); g_assert_cmphex(res, ==, UINT_MAX); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); g_free(str); } @@ -732,7 +732,7 @@ static void test_qemu_strtoui_underflow(void) g_assert_cmpint(err, ==, -ERANGE); g_assert_cmpuint(res, ==, (unsigned int)-1); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); g_free(str); } @@ -748,7 +748,7 @@ static void test_qemu_strtoui_negative(void) g_assert_cmpint(err, ==, 0); g_assert_cmpuint(res, ==, (unsigned int)-321); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); } static void test_qemu_strtoui_full_correct(void) @@ -830,7 +830,7 @@ static void test_qemu_strtol_correct(void) g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, 12345); - g_assert(endptr == str + 5); + g_assert_true(endptr == str + 5); } static void test_qemu_strtol_null(void) @@ -843,7 +843,7 @@ static void test_qemu_strtol_null(void) err = qemu_strtol(NULL, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert(endptr == NULL); + g_assert_null(endptr); } static void test_qemu_strtol_empty(void) @@ -857,7 +857,7 @@ static void test_qemu_strtol_empty(void) err = qemu_strtol(str, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert(endptr == str); + g_assert_true(endptr == str); } static void test_qemu_strtol_whitespace(void) @@ -871,7 +871,7 @@ static void test_qemu_strtol_whitespace(void) err = qemu_strtol(str, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert(endptr == str); + g_assert_true(endptr == str); } static void test_qemu_strtol_invalid(void) @@ -885,7 +885,7 @@ static void test_qemu_strtol_invalid(void) err = qemu_strtol(str, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert(endptr == str); + g_assert_true(endptr == str); } static void test_qemu_strtol_trailing(void) @@ -900,7 +900,7 @@ static void test_qemu_strtol_trailing(void) g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, 123); - g_assert(endptr == str + 3); + g_assert_true(endptr == str + 3); } static void test_qemu_strtol_octal(void) @@ -915,7 +915,7 @@ static void test_qemu_strtol_octal(void) g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, 0123); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); res = 999; endptr = &f; @@ -923,7 +923,7 @@ static void test_qemu_strtol_octal(void) g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, 0123); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); } static void test_qemu_strtol_decimal(void) @@ -938,7 +938,7 @@ static void test_qemu_strtol_decimal(void) g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, 123); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); str = "123"; res = 999; @@ -947,7 +947,7 @@ static void test_qemu_strtol_decimal(void) g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, 123); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); } static void test_qemu_strtol_hex(void) @@ -962,7 +962,7 @@ static void test_qemu_strtol_hex(void) g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, 0x123); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); str = "0x123"; res = 999; @@ -971,7 +971,7 @@ static void test_qemu_strtol_hex(void) g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, 0x123); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); str = "0x"; res = 999; @@ -980,7 +980,7 @@ static void test_qemu_strtol_hex(void) g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, 0); - g_assert(endptr == str + 1); + g_assert_true(endptr == str + 1); } static void test_qemu_strtol_max(void) @@ -995,7 +995,7 @@ static void test_qemu_strtol_max(void) g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, LONG_MAX); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); g_free(str); } @@ -1011,7 +1011,7 @@ static void test_qemu_strtol_overflow(void) g_assert_cmpint(err, ==, -ERANGE); g_assert_cmpint(res, ==, LONG_MAX); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); } static void test_qemu_strtol_underflow(void) @@ -1026,7 +1026,7 @@ static void test_qemu_strtol_underflow(void) g_assert_cmpint(err, ==, -ERANGE); g_assert_cmpint(res, ==, LONG_MIN); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); } static void test_qemu_strtol_negative(void) @@ -1041,7 +1041,7 @@ static void test_qemu_strtol_negative(void) g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, -321); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); } static void test_qemu_strtol_full_correct(void) @@ -1066,7 +1066,7 @@ static void test_qemu_strtol_full_null(void) err = qemu_strtol(NULL, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert(endptr == NULL); + g_assert_null(endptr); } static void test_qemu_strtol_full_empty(void) @@ -1128,7 +1128,7 @@ static void test_qemu_strtoul_correct(void) g_assert_cmpint(err, ==, 0); g_assert_cmpuint(res, ==, 12345); - g_assert(endptr == str + 5); + g_assert_true(endptr == str + 5); } static void test_qemu_strtoul_null(void) @@ -1141,7 +1141,7 @@ static void test_qemu_strtoul_null(void) err = qemu_strtoul(NULL, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert(endptr == NULL); + g_assert_null(endptr); } static void test_qemu_strtoul_empty(void) @@ -1155,7 +1155,7 @@ static void test_qemu_strtoul_empty(void) err = qemu_strtoul(str, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert(endptr == str); + g_assert_true(endptr == str); } static void test_qemu_strtoul_whitespace(void) @@ -1169,7 +1169,7 @@ static void test_qemu_strtoul_whitespace(void) err = qemu_strtoul(str, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert(endptr == str); + g_assert_true(endptr == str); } static void test_qemu_strtoul_invalid(void) @@ -1183,7 +1183,7 @@ static void test_qemu_strtoul_invalid(void) err = qemu_strtoul(str, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert(endptr == str); + g_assert_true(endptr == str); } static void test_qemu_strtoul_trailing(void) @@ -1198,7 +1198,7 @@ static void test_qemu_strtoul_trailing(void) g_assert_cmpint(err, ==, 0); g_assert_cmpuint(res, ==, 123); - g_assert(endptr == str + 3); + g_assert_true(endptr == str + 3); } static void test_qemu_strtoul_octal(void) @@ -1213,7 +1213,7 @@ static void test_qemu_strtoul_octal(void) g_assert_cmpint(err, ==, 0); g_assert_cmpuint(res, ==, 0123); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); res = 999; endptr = &f; @@ -1221,7 +1221,7 @@ static void test_qemu_strtoul_octal(void) g_assert_cmpint(err, ==, 0); g_assert_cmpuint(res, ==, 0123); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); } static void test_qemu_strtoul_decimal(void) @@ -1236,7 +1236,7 @@ static void test_qemu_strtoul_decimal(void) g_assert_cmpint(err, ==, 0); g_assert_cmpuint(res, ==, 123); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); str = "123"; res = 999; @@ -1245,7 +1245,7 @@ static void test_qemu_strtoul_decimal(void) g_assert_cmpint(err, ==, 0); g_assert_cmpuint(res, ==, 123); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); } static void test_qemu_strtoul_hex(void) @@ -1260,7 +1260,7 @@ static void test_qemu_strtoul_hex(void) g_assert_cmpint(err, ==, 0); g_assert_cmphex(res, ==, 0x123); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); str = "0x123"; res = 999; @@ -1269,7 +1269,7 @@ static void test_qemu_strtoul_hex(void) g_assert_cmpint(err, ==, 0); g_assert_cmphex(res, ==, 0x123); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); str = "0x"; res = 999; @@ -1278,7 +1278,7 @@ static void test_qemu_strtoul_hex(void) g_assert_cmpint(err, ==, 0); g_assert_cmphex(res, ==, 0); - g_assert(endptr == str + 1); + g_assert_true(endptr == str + 1); } static void test_qemu_strtoul_max(void) @@ -1293,7 +1293,7 @@ static void test_qemu_strtoul_max(void) g_assert_cmpint(err, ==, 0); g_assert_cmphex(res, ==, ULONG_MAX); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); g_free(str); } @@ -1309,7 +1309,7 @@ static void test_qemu_strtoul_overflow(void) g_assert_cmpint(err, ==, -ERANGE); g_assert_cmphex(res, ==, ULONG_MAX); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); } static void test_qemu_strtoul_underflow(void) @@ -1324,7 +1324,7 @@ static void test_qemu_strtoul_underflow(void) g_assert_cmpint(err, ==, -ERANGE); g_assert_cmpuint(res, ==, -1ul); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); } static void test_qemu_strtoul_negative(void) @@ -1339,7 +1339,7 @@ static void test_qemu_strtoul_negative(void) g_assert_cmpint(err, ==, 0); g_assert_cmpuint(res, ==, -321ul); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); } static void test_qemu_strtoul_full_correct(void) @@ -1421,7 +1421,7 @@ static void test_qemu_strtoi64_correct(void) g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, 12345); - g_assert(endptr == str + 5); + g_assert_true(endptr == str + 5); } static void test_qemu_strtoi64_null(void) @@ -1434,7 +1434,7 @@ static void test_qemu_strtoi64_null(void) err = qemu_strtoi64(NULL, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert(endptr == NULL); + g_assert_null(endptr); } static void test_qemu_strtoi64_empty(void) @@ -1448,7 +1448,7 @@ static void test_qemu_strtoi64_empty(void) err = qemu_strtoi64(str, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert(endptr == str); + g_assert_true(endptr == str); } static void test_qemu_strtoi64_whitespace(void) @@ -1462,7 +1462,7 @@ static void test_qemu_strtoi64_whitespace(void) err = qemu_strtoi64(str, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert(endptr == str); + g_assert_true(endptr == str); } static void test_qemu_strtoi64_invalid(void) @@ -1476,7 +1476,7 @@ static void test_qemu_strtoi64_invalid(void) err = qemu_strtoi64(str, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert(endptr == str); + g_assert_true(endptr == str); } static void test_qemu_strtoi64_trailing(void) @@ -1491,7 +1491,7 @@ static void test_qemu_strtoi64_trailing(void) g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, 123); - g_assert(endptr == str + 3); + g_assert_true(endptr == str + 3); } static void test_qemu_strtoi64_octal(void) @@ -1506,7 +1506,7 @@ static void test_qemu_strtoi64_octal(void) g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, 0123); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); endptr = &f; res = 999; @@ -1514,7 +1514,7 @@ static void test_qemu_strtoi64_octal(void) g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, 0123); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); } static void test_qemu_strtoi64_decimal(void) @@ -1529,7 +1529,7 @@ static void test_qemu_strtoi64_decimal(void) g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, 123); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); str = "123"; endptr = &f; @@ -1538,7 +1538,7 @@ static void test_qemu_strtoi64_decimal(void) g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, 123); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); } static void test_qemu_strtoi64_hex(void) @@ -1553,7 +1553,7 @@ static void test_qemu_strtoi64_hex(void) g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, 0x123); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); str = "0x123"; endptr = &f; @@ -1562,7 +1562,7 @@ static void test_qemu_strtoi64_hex(void) g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, 0x123); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); str = "0x"; endptr = &f; @@ -1571,7 +1571,7 @@ static void test_qemu_strtoi64_hex(void) g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, 0); - g_assert(endptr == str + 1); + g_assert_true(endptr == str + 1); } static void test_qemu_strtoi64_max(void) @@ -1586,7 +1586,7 @@ static void test_qemu_strtoi64_max(void) g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, LLONG_MAX); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); g_free(str); } @@ -1602,7 +1602,7 @@ static void test_qemu_strtoi64_overflow(void) g_assert_cmpint(err, ==, -ERANGE); g_assert_cmpint(res, ==, LLONG_MAX); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); } static void test_qemu_strtoi64_underflow(void) @@ -1617,7 +1617,7 @@ static void test_qemu_strtoi64_underflow(void) g_assert_cmpint(err, ==, -ERANGE); g_assert_cmpint(res, ==, LLONG_MIN); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); } static void test_qemu_strtoi64_negative(void) @@ -1632,7 +1632,7 @@ static void test_qemu_strtoi64_negative(void) g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, -321); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); } static void test_qemu_strtoi64_full_correct(void) @@ -1717,7 +1717,7 @@ static void test_qemu_strtou64_correct(void) g_assert_cmpint(err, ==, 0); g_assert_cmpuint(res, ==, 12345); - g_assert(endptr == str + 5); + g_assert_true(endptr == str + 5); } static void test_qemu_strtou64_null(void) @@ -1730,7 +1730,7 @@ static void test_qemu_strtou64_null(void) err = qemu_strtou64(NULL, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert(endptr == NULL); + g_assert_null(endptr); } static void test_qemu_strtou64_empty(void) @@ -1744,7 +1744,7 @@ static void test_qemu_strtou64_empty(void) err = qemu_strtou64(str, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert(endptr == str); + g_assert_true(endptr == str); } static void test_qemu_strtou64_whitespace(void) @@ -1758,7 +1758,7 @@ static void test_qemu_strtou64_whitespace(void) err = qemu_strtou64(str, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert(endptr == str); + g_assert_true(endptr == str); } static void test_qemu_strtou64_invalid(void) @@ -1772,7 +1772,7 @@ static void test_qemu_strtou64_invalid(void) err = qemu_strtou64(str, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert(endptr == str); + g_assert_true(endptr == str); } static void test_qemu_strtou64_trailing(void) @@ -1787,7 +1787,7 @@ static void test_qemu_strtou64_trailing(void) g_assert_cmpint(err, ==, 0); g_assert_cmpuint(res, ==, 123); - g_assert(endptr == str + 3); + g_assert_true(endptr == str + 3); } static void test_qemu_strtou64_octal(void) @@ -1802,7 +1802,7 @@ static void test_qemu_strtou64_octal(void) g_assert_cmpint(err, ==, 0); g_assert_cmpuint(res, ==, 0123); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); endptr = &f; res = 999; @@ -1810,7 +1810,7 @@ static void test_qemu_strtou64_octal(void) g_assert_cmpint(err, ==, 0); g_assert_cmpuint(res, ==, 0123); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); } static void test_qemu_strtou64_decimal(void) @@ -1825,7 +1825,7 @@ static void test_qemu_strtou64_decimal(void) g_assert_cmpint(err, ==, 0); g_assert_cmpuint(res, ==, 123); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); str = "123"; endptr = &f; @@ -1834,7 +1834,7 @@ static void test_qemu_strtou64_decimal(void) g_assert_cmpint(err, ==, 0); g_assert_cmpuint(res, ==, 123); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); } static void test_qemu_strtou64_hex(void) @@ -1849,7 +1849,7 @@ static void test_qemu_strtou64_hex(void) g_assert_cmpint(err, ==, 0); g_assert_cmphex(res, ==, 0x123); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); str = "0x123"; endptr = &f; @@ -1858,7 +1858,7 @@ static void test_qemu_strtou64_hex(void) g_assert_cmpint(err, ==, 0); g_assert_cmphex(res, ==, 0x123); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); str = "0x"; endptr = &f; @@ -1867,7 +1867,7 @@ static void test_qemu_strtou64_hex(void) g_assert_cmpint(err, ==, 0); g_assert_cmphex(res, ==, 0); - g_assert(endptr == str + 1); + g_assert_true(endptr == str + 1); } static void test_qemu_strtou64_max(void) @@ -1882,7 +1882,7 @@ static void test_qemu_strtou64_max(void) g_assert_cmpint(err, ==, 0); g_assert_cmphex(res, ==, ULLONG_MAX); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); g_free(str); } @@ -1898,7 +1898,7 @@ static void test_qemu_strtou64_overflow(void) g_assert_cmpint(err, ==, -ERANGE); g_assert_cmphex(res, ==, ULLONG_MAX); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); } static void test_qemu_strtou64_underflow(void) @@ -1913,7 +1913,7 @@ static void test_qemu_strtou64_underflow(void) g_assert_cmpint(err, ==, -ERANGE); g_assert_cmphex(res, ==, -1ull); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); } static void test_qemu_strtou64_negative(void) @@ -1928,7 +1928,7 @@ static void test_qemu_strtou64_negative(void) g_assert_cmpint(err, ==, 0); g_assert_cmpuint(res, ==, -321ull); - g_assert(endptr == str + strlen(str)); + g_assert_true(endptr == str + strlen(str)); } static void test_qemu_strtou64_full_correct(void) @@ -2013,7 +2013,7 @@ static void test_qemu_strtosz_simple(void) err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, 0); - g_assert(endptr == str + 1); + g_assert_true(endptr == str + 1); /* Leading 0 gives decimal results, not octal */ str = "08"; @@ -2022,7 +2022,7 @@ static void test_qemu_strtosz_simple(void) err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, 8); - g_assert(endptr == str + 2); + g_assert_true(endptr == str + 2); /* Leading space is ignored */ str = " 12345"; @@ -2031,7 +2031,7 @@ static void test_qemu_strtosz_simple(void) err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, 12345); - g_assert(endptr == str + 6); + g_assert_true(endptr == str + 6); res = 0xbaadf00d; err = qemu_strtosz(str, NULL, &res); @@ -2044,7 +2044,7 @@ static void test_qemu_strtosz_simple(void) err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, 0x1fffffffffffff); - g_assert(endptr == str + 16); + g_assert_true(endptr == str + 16); str = "9007199254740992"; /* 2^53 */ endptr = str; @@ -2052,7 +2052,7 @@ static void test_qemu_strtosz_simple(void) err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, 0x20000000000000); - g_assert(endptr == str + 16); + g_assert_true(endptr == str + 16); str = "9007199254740993"; /* 2^53+1 */ endptr = str; @@ -2060,7 +2060,7 @@ static void test_qemu_strtosz_simple(void) err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, 0x20000000000001); - g_assert(endptr == str + 16); + g_assert_true(endptr == str + 16); str = "18446744073709549568"; /* 0xfffffffffffff800 (53 msbs set) */ endptr = str; @@ -2068,7 +2068,7 @@ static void test_qemu_strtosz_simple(void) err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, 0xfffffffffffff800); - g_assert(endptr == str + 20); + g_assert_true(endptr == str + 20); str = "18446744073709550591"; /* 0xfffffffffffffbff */ endptr = str; @@ -2076,7 +2076,7 @@ static void test_qemu_strtosz_simple(void) err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, 0xfffffffffffffbff); - g_assert(endptr == str + 20); + g_assert_true(endptr == str + 20); str = "18446744073709551615"; /* 0xffffffffffffffff */ endptr = str; @@ -2084,7 +2084,7 @@ static void test_qemu_strtosz_simple(void) err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, 0xffffffffffffffff); - g_assert(endptr == str + 20); + g_assert_true(endptr == str + 20); } static void test_qemu_strtosz_hex(void) @@ -2100,7 +2100,7 @@ static void test_qemu_strtosz_hex(void) err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, 0); - g_assert(endptr == str + 3); + g_assert_true(endptr == str + 3); str = "0xab"; endptr = str; @@ -2108,7 +2108,7 @@ static void test_qemu_strtosz_hex(void) err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, 171); - g_assert(endptr == str + 4); + g_assert_true(endptr == str + 4); str = "0xae"; endptr = str; @@ -2116,7 +2116,7 @@ static void test_qemu_strtosz_hex(void) err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, 174); - g_assert(endptr == str + 4); + g_assert_true(endptr == str + 4); } static void test_qemu_strtosz_units(void) @@ -2139,56 +2139,56 @@ static void test_qemu_strtosz_units(void) err = qemu_strtosz_MiB(none, &endptr, &res); g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, MiB); - g_assert(endptr == none + 1); + g_assert_true(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); + g_assert_true(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); + g_assert_true(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); + g_assert_true(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); + g_assert_true(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); + g_assert_true(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); + g_assert_true(endptr == p + 2); endptr = NULL; res = 0xbaadf00d; err = qemu_strtosz(e, &endptr, &res); g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, EiB); - g_assert(endptr == e + 2); + g_assert_true(endptr == e + 2); } static void test_qemu_strtosz_float(void) @@ -2204,7 +2204,7 @@ static void test_qemu_strtosz_float(void) err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, EiB / 2); - g_assert(endptr == str + 4); + g_assert_true(endptr == str + 4); /* For convenience, a fraction of 0 is tolerated even on bytes */ str = "1.0B"; @@ -2213,7 +2213,7 @@ static void test_qemu_strtosz_float(void) err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, 1); - g_assert(endptr == str + 4); + g_assert_true(endptr == str + 4); /* An empty fraction is tolerated */ str = "1.k"; @@ -2222,7 +2222,7 @@ static void test_qemu_strtosz_float(void) err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, 1024); - g_assert(endptr == str + 3); + g_assert_true(endptr == str + 3); /* For convenience, we permit values that are not byte-exact */ str = "12.345M"; @@ -2231,7 +2231,7 @@ static void test_qemu_strtosz_float(void) err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, (uint64_t) (12.345 * MiB + 0.5)); - g_assert(endptr == str + 7); + g_assert_true(endptr == str + 7); } static void test_qemu_strtosz_invalid(void) @@ -2246,35 +2246,35 @@ static void test_qemu_strtosz_invalid(void) err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); g_assert_cmpint(res, ==, 0xbaadf00d); - g_assert(endptr == str); + g_assert_true(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); + g_assert_true(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); + g_assert_true(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); + g_assert_true(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); + g_assert_true(endptr == str); /* Fractional values require scale larger than bytes */ str = "1.1B"; @@ -2282,14 +2282,14 @@ static void test_qemu_strtosz_invalid(void) err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); g_assert_cmpint(res, ==, 0xbaadf00d); - g_assert(endptr == str); + g_assert_true(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); + g_assert_true(endptr == str); /* No floating point exponents */ str = "1.5e1k"; @@ -2297,14 +2297,14 @@ static void test_qemu_strtosz_invalid(void) err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); g_assert_cmpint(res, ==, 0xbaadf00d); - g_assert(endptr == str); + g_assert_true(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); + g_assert_true(endptr == str); /* No hex fractions */ str = "0x1.8k"; @@ -2312,7 +2312,7 @@ static void test_qemu_strtosz_invalid(void) err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); g_assert_cmpint(res, ==, 0xbaadf00d); - g_assert(endptr == str); + g_assert_true(endptr == str); /* No suffixes */ str = "0x18M"; @@ -2320,7 +2320,7 @@ static void test_qemu_strtosz_invalid(void) err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); g_assert_cmpint(res, ==, 0xbaadf00d); - g_assert(endptr == str); + g_assert_true(endptr == str); /* No negative values */ str = "-0"; @@ -2328,14 +2328,14 @@ static void test_qemu_strtosz_invalid(void) err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); g_assert_cmpint(res, ==, 0xbaadf00d); - g_assert(endptr == str); + g_assert_true(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); + g_assert_true(endptr == str); } static void test_qemu_strtosz_trailing(void) @@ -2351,7 +2351,7 @@ static void test_qemu_strtosz_trailing(void) err = qemu_strtosz_MiB(str, &endptr, &res); g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, 123 * MiB); - g_assert(endptr == str + 3); + g_assert_true(endptr == str + 3); res = 0xbaadf00d; err = qemu_strtosz(str, NULL, &res); @@ -2364,7 +2364,7 @@ static void test_qemu_strtosz_trailing(void) err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, 1024); - g_assert(endptr == str + 2); + g_assert_true(endptr == str + 2); res = 0xbaadf00d; err = qemu_strtosz(str, NULL, &res); @@ -2377,7 +2377,7 @@ static void test_qemu_strtosz_trailing(void) err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, 0); - g_assert(endptr == str + 1); + g_assert_true(endptr == str + 1); res = 0xbaadf00d; err = qemu_strtosz(str, NULL, &res); @@ -2390,7 +2390,7 @@ static void test_qemu_strtosz_trailing(void) err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, 0); - g_assert(endptr == str + 2); + g_assert_true(endptr == str + 2); res = 0xbaadf00d; err = qemu_strtosz(str, NULL, &res); @@ -2403,7 +2403,7 @@ static void test_qemu_strtosz_trailing(void) err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, 123); - g_assert(endptr == str + 3); + g_assert_true(endptr == str + 3); res = 0xbaadf00d; err = qemu_strtosz(str, NULL, &res); @@ -2423,14 +2423,14 @@ static void test_qemu_strtosz_erange(void) err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -ERANGE); g_assert_cmpint(res, ==, 0xbaadf00d); - g_assert(endptr == str + 20); + g_assert_true(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); + g_assert_true(endptr == str + 3); } static void test_qemu_strtosz_metric(void) @@ -2446,7 +2446,7 @@ static void test_qemu_strtosz_metric(void) err = qemu_strtosz_metric(str, &endptr, &res); g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, 12345000); - g_assert(endptr == str + 6); + g_assert_true(endptr == str + 6); str = "12.345M"; endptr = str; @@ -2454,7 +2454,7 @@ static void test_qemu_strtosz_metric(void) err = qemu_strtosz_metric(str, &endptr, &res); g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, 12345000); - g_assert(endptr == str + 7); + g_assert_true(endptr == str + 7); } static void test_freq_to_str(void) From patchwork Mon May 8 20:03:34 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Blake X-Patchwork-Id: 13235005 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 883CEC77B7F for ; Mon, 8 May 2023 20:06:09 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pw75a-0006GA-Ok; Mon, 08 May 2023 16:04:06 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pw75N-0006EK-4v for qemu-devel@nongnu.org; Mon, 08 May 2023 16:03:54 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pw75I-0007Iu-UL for qemu-devel@nongnu.org; Mon, 08 May 2023 16:03:51 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1683576228; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=LMW4h9VLsVkZ3hPefbGMWaCLCTsFeVwZ8onLHu0sup4=; b=YoZDUgT6oT2JTwHY2t+NAjo3gbpG+8yCQfI8T6mjM+4ajYOZtzvcC+fArrq/PMv8fnzMPS WSCLfWqBTd9Oa3NxcGcZFm8FO0898sOnTJISZsEX7elpO/+JKvzE0vgT3pZLgqIZhT6m8f LsOiEJMum0rJ1LHMye+YyX0EC+PnTeM= Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-671-1XkWt8w9M_GbGstMe5DhvA-1; Mon, 08 May 2023 16:03:46 -0400 X-MC-Unique: 1XkWt8w9M_GbGstMe5DhvA-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 7457538237C4 for ; Mon, 8 May 2023 20:03:46 +0000 (UTC) Received: from green.redhat.com (unknown [10.2.16.49]) by smtp.corp.redhat.com (Postfix) with ESMTP id 2E6F91121314; Mon, 8 May 2023 20:03:46 +0000 (UTC) From: Eric Blake To: qemu-devel@nongnu.org Cc: hreitz@redhat.com Subject: [PATCH 02/11] test-cutils: Use g_assert_cmpuint where appropriate Date: Mon, 8 May 2023 15:03:34 -0500 Message-Id: <20230508200343.791450-3-eblake@redhat.com> In-Reply-To: <20230508200343.791450-1-eblake@redhat.com> References: <20230508200343.791450-1-eblake@redhat.com> MIME-Version: 1.0 Content-type: text/plain X-Scanned-By: MIMEDefang 3.1 on 10.11.54.3 Received-SPF: pass client-ip=170.10.129.124; envelope-from=eblake@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org When debugging test failures, seeing unsigned values as large positive values rather than negative values matters (assuming that the bug in glib 2.76 [1] where g_assert_cmpuint displays signed instead of unsigned values will eventually be fixed). No impact when the test is passing, but using a consistent style will matter more in upcoming test additions. Also, some tests are better with cmphex. While at it, fix some spacing and minor typing issues spotted nearby. [1] https://gitlab.gnome.org/GNOME/glib/-/issues/2997 Signed-off-by: Eric Blake --- tests/unit/test-cutils.c | 148 +++++++++++++++++++-------------------- 1 file changed, 74 insertions(+), 74 deletions(-) diff --git a/tests/unit/test-cutils.c b/tests/unit/test-cutils.c index 0202ac0d5b3..38bd3990207 100644 --- a/tests/unit/test-cutils.c +++ b/tests/unit/test-cutils.c @@ -39,7 +39,7 @@ static void test_parse_uint_null(void) r = parse_uint(NULL, &i, &endptr, 0); g_assert_cmpint(r, ==, -EINVAL); - g_assert_cmpint(i, ==, 0); + g_assert_cmpuint(i, ==, 0); g_assert_null(endptr); } @@ -54,7 +54,7 @@ static void test_parse_uint_empty(void) r = parse_uint(str, &i, &endptr, 0); g_assert_cmpint(r, ==, -EINVAL); - g_assert_cmpint(i, ==, 0); + g_assert_cmpuint(i, ==, 0); g_assert_true(endptr == str); } @@ -69,7 +69,7 @@ static void test_parse_uint_whitespace(void) r = parse_uint(str, &i, &endptr, 0); g_assert_cmpint(r, ==, -EINVAL); - g_assert_cmpint(i, ==, 0); + g_assert_cmpuint(i, ==, 0); g_assert_true(endptr == str); } @@ -85,7 +85,7 @@ static void test_parse_uint_invalid(void) r = parse_uint(str, &i, &endptr, 0); g_assert_cmpint(r, ==, -EINVAL); - g_assert_cmpint(i, ==, 0); + g_assert_cmpuint(i, ==, 0); g_assert_true(endptr == str); } @@ -101,7 +101,7 @@ static void test_parse_uint_trailing(void) r = parse_uint(str, &i, &endptr, 0); g_assert_cmpint(r, ==, 0); - g_assert_cmpint(i, ==, 123); + g_assert_cmpuint(i, ==, 123); g_assert_true(endptr == str + 3); } @@ -116,7 +116,7 @@ static void test_parse_uint_correct(void) r = parse_uint(str, &i, &endptr, 0); g_assert_cmpint(r, ==, 0); - g_assert_cmpint(i, ==, 123); + g_assert_cmpuint(i, ==, 123); g_assert_true(endptr == str + strlen(str)); } @@ -131,7 +131,7 @@ static void test_parse_uint_octal(void) r = parse_uint(str, &i, &endptr, 0); g_assert_cmpint(r, ==, 0); - g_assert_cmpint(i, ==, 0123); + g_assert_cmpuint(i, ==, 0123); g_assert_true(endptr == str + strlen(str)); } @@ -146,7 +146,7 @@ static void test_parse_uint_decimal(void) r = parse_uint(str, &i, &endptr, 10); g_assert_cmpint(r, ==, 0); - g_assert_cmpint(i, ==, 123); + g_assert_cmpuint(i, ==, 123); g_assert_true(endptr == str + strlen(str)); } @@ -162,7 +162,7 @@ static void test_parse_uint_llong_max(void) r = parse_uint(str, &i, &endptr, 0); g_assert_cmpint(r, ==, 0); - g_assert_cmpint(i, ==, (unsigned long long)LLONG_MAX + 1); + g_assert_cmpuint(i, ==, (unsigned long long)LLONG_MAX + 1); g_assert_true(endptr == str + strlen(str)); g_free(str); @@ -179,7 +179,7 @@ static void test_parse_uint_overflow(void) r = parse_uint(str, &i, &endptr, 0); g_assert_cmpint(r, ==, -ERANGE); - g_assert_cmpint(i, ==, ULLONG_MAX); + g_assert_cmpuint(i, ==, ULLONG_MAX); g_assert_true(endptr == str + strlen(str)); } @@ -194,7 +194,7 @@ static void test_parse_uint_negative(void) r = parse_uint(str, &i, &endptr, 0); g_assert_cmpint(r, ==, -ERANGE); - g_assert_cmpint(i, ==, 0); + g_assert_cmpuint(i, ==, 0); g_assert_true(endptr == str + strlen(str)); } @@ -208,7 +208,7 @@ static void test_parse_uint_full_trailing(void) r = parse_uint_full(str, &i, 0); g_assert_cmpint(r, ==, -EINVAL); - g_assert_cmpint(i, ==, 0); + g_assert_cmpuint(i, ==, 0); } static void test_parse_uint_full_correct(void) @@ -220,7 +220,7 @@ static void test_parse_uint_full_correct(void) r = parse_uint_full(str, &i, 0); g_assert_cmpint(r, ==, 0); - g_assert_cmpint(i, ==, 123); + g_assert_cmpuint(i, ==, 123); } static void test_qemu_strtoi_correct(void) @@ -428,7 +428,7 @@ static void test_qemu_strtoi_underflow(void) int res = 999; int err; - err = qemu_strtoi(str, &endptr, 0, &res); + err = qemu_strtoi(str, &endptr, 0, &res); g_assert_cmpint(err, ==, -ERANGE); g_assert_cmpint(res, ==, INT_MIN); @@ -479,10 +479,10 @@ static void test_qemu_strtoi_full_null(void) static void test_qemu_strtoi_full_empty(void) { const char *str = ""; - int res = 999L; + int res = 999; int err; - err = qemu_strtoi(str, NULL, 0, &res); + err = qemu_strtoi(str, NULL, 0, &res); g_assert_cmpint(err, ==, -EINVAL); } @@ -728,7 +728,7 @@ static void test_qemu_strtoui_underflow(void) unsigned int res = 999; int err; - err = qemu_strtoui(str, &endptr, 0, &res); + err = qemu_strtoui(str, &endptr, 0, &res); g_assert_cmpint(err, ==, -ERANGE); g_assert_cmpuint(res, ==, (unsigned int)-1); @@ -1022,7 +1022,7 @@ static void test_qemu_strtol_underflow(void) long res = 999; int err; - err = qemu_strtol(str, &endptr, 0, &res); + err = qemu_strtol(str, &endptr, 0, &res); g_assert_cmpint(err, ==, -ERANGE); g_assert_cmpint(res, ==, LONG_MIN); @@ -1075,7 +1075,7 @@ static void test_qemu_strtol_full_empty(void) long res = 999L; int err; - err = qemu_strtol(str, NULL, 0, &res); + err = qemu_strtol(str, NULL, 0, &res); g_assert_cmpint(err, ==, -EINVAL); } @@ -1320,7 +1320,7 @@ static void test_qemu_strtoul_underflow(void) unsigned long res = 999; int err; - err = qemu_strtoul(str, &endptr, 0, &res); + err = qemu_strtoul(str, &endptr, 0, &res); g_assert_cmpint(err, ==, -ERANGE); g_assert_cmpuint(res, ==, -1ul); @@ -1613,7 +1613,7 @@ static void test_qemu_strtoi64_underflow(void) int64_t res = 999; int err; - err = qemu_strtoi64(str, &endptr, 0, &res); + err = qemu_strtoi64(str, &endptr, 0, &res); g_assert_cmpint(err, ==, -ERANGE); g_assert_cmpint(res, ==, LLONG_MIN); @@ -1909,7 +1909,7 @@ static void test_qemu_strtou64_underflow(void) uint64_t res = 999; int err; - err = qemu_strtou64(str, &endptr, 0, &res); + err = qemu_strtou64(str, &endptr, 0, &res); g_assert_cmpint(err, ==, -ERANGE); g_assert_cmphex(res, ==, -1ull); @@ -2012,7 +2012,7 @@ static void test_qemu_strtosz_simple(void) res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, 0); - g_assert_cmpint(res, ==, 0); + g_assert_cmpuint(res, ==, 0); g_assert_true(endptr == str + 1); /* Leading 0 gives decimal results, not octal */ @@ -2021,7 +2021,7 @@ static void test_qemu_strtosz_simple(void) res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, 0); - g_assert_cmpint(res, ==, 8); + g_assert_cmpuint(res, ==, 8); g_assert_true(endptr == str + 2); /* Leading space is ignored */ @@ -2030,20 +2030,20 @@ static void test_qemu_strtosz_simple(void) res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, 0); - g_assert_cmpint(res, ==, 12345); + g_assert_cmpuint(res, ==, 12345); g_assert_true(endptr == str + 6); res = 0xbaadf00d; err = qemu_strtosz(str, NULL, &res); g_assert_cmpint(err, ==, 0); - g_assert_cmpint(res, ==, 12345); + g_assert_cmpuint(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_cmphex(res, ==, 0x1fffffffffffffULL); g_assert_true(endptr == str + 16); str = "9007199254740992"; /* 2^53 */ @@ -2051,7 +2051,7 @@ static void test_qemu_strtosz_simple(void) res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, 0); - g_assert_cmpint(res, ==, 0x20000000000000); + g_assert_cmphex(res, ==, 0x20000000000000ULL); g_assert_true(endptr == str + 16); str = "9007199254740993"; /* 2^53+1 */ @@ -2059,7 +2059,7 @@ static void test_qemu_strtosz_simple(void) res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, 0); - g_assert_cmpint(res, ==, 0x20000000000001); + g_assert_cmphex(res, ==, 0x20000000000001ULL); g_assert_true(endptr == str + 16); str = "18446744073709549568"; /* 0xfffffffffffff800 (53 msbs set) */ @@ -2067,7 +2067,7 @@ static void test_qemu_strtosz_simple(void) res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, 0); - g_assert_cmpint(res, ==, 0xfffffffffffff800); + g_assert_cmphex(res, ==, 0xfffffffffffff800ULL); g_assert_true(endptr == str + 20); str = "18446744073709550591"; /* 0xfffffffffffffbff */ @@ -2075,7 +2075,7 @@ static void test_qemu_strtosz_simple(void) res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, 0); - g_assert_cmpint(res, ==, 0xfffffffffffffbff); + g_assert_cmphex(res, ==, 0xfffffffffffffbffULL); g_assert_true(endptr == str + 20); str = "18446744073709551615"; /* 0xffffffffffffffff */ @@ -2083,7 +2083,7 @@ static void test_qemu_strtosz_simple(void) res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, 0); - g_assert_cmpint(res, ==, 0xffffffffffffffff); + g_assert_cmphex(res, ==, 0xffffffffffffffffULL); g_assert_true(endptr == str + 20); } @@ -2099,7 +2099,7 @@ static void test_qemu_strtosz_hex(void) res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, 0); - g_assert_cmpint(res, ==, 0); + g_assert_cmpuint(res, ==, 0); g_assert_true(endptr == str + 3); str = "0xab"; @@ -2107,7 +2107,7 @@ static void test_qemu_strtosz_hex(void) res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, 0); - g_assert_cmpint(res, ==, 171); + g_assert_cmpuint(res, ==, 171); g_assert_true(endptr == str + 4); str = "0xae"; @@ -2115,7 +2115,7 @@ static void test_qemu_strtosz_hex(void) res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, 0); - g_assert_cmpint(res, ==, 174); + g_assert_cmpuint(res, ==, 174); g_assert_true(endptr == str + 4); } @@ -2138,56 +2138,56 @@ static void test_qemu_strtosz_units(void) res = 0xbaadf00d; err = qemu_strtosz_MiB(none, &endptr, &res); g_assert_cmpint(err, ==, 0); - g_assert_cmpint(res, ==, MiB); + g_assert_cmpuint(res, ==, MiB); g_assert_true(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_cmpuint(res, ==, 1); g_assert_true(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_cmpuint(res, ==, KiB); g_assert_true(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_cmpuint(res, ==, MiB); g_assert_true(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_cmpuint(res, ==, GiB); g_assert_true(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_cmpuint(res, ==, TiB); g_assert_true(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_cmpuint(res, ==, PiB); g_assert_true(endptr == p + 2); endptr = NULL; res = 0xbaadf00d; err = qemu_strtosz(e, &endptr, &res); g_assert_cmpint(err, ==, 0); - g_assert_cmpint(res, ==, EiB); + g_assert_cmpuint(res, ==, EiB); g_assert_true(endptr == e + 2); } @@ -2203,7 +2203,7 @@ static void test_qemu_strtosz_float(void) res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, 0); - g_assert_cmpint(res, ==, EiB / 2); + g_assert_cmpuint(res, ==, EiB / 2); g_assert_true(endptr == str + 4); /* For convenience, a fraction of 0 is tolerated even on bytes */ @@ -2212,7 +2212,7 @@ static void test_qemu_strtosz_float(void) res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, 0); - g_assert_cmpint(res, ==, 1); + g_assert_cmpuint(res, ==, 1); g_assert_true(endptr == str + 4); /* An empty fraction is tolerated */ @@ -2221,7 +2221,7 @@ static void test_qemu_strtosz_float(void) res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, 0); - g_assert_cmpint(res, ==, 1024); + g_assert_cmpuint(res, ==, 1024); g_assert_true(endptr == str + 3); /* For convenience, we permit values that are not byte-exact */ @@ -2230,7 +2230,7 @@ static void test_qemu_strtosz_float(void) res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, 0); - g_assert_cmpint(res, ==, (uint64_t) (12.345 * MiB + 0.5)); + g_assert_cmpuint(res, ==, (uint64_t) (12.345 * MiB + 0.5)); g_assert_true(endptr == str + 7); } @@ -2245,35 +2245,35 @@ static void test_qemu_strtosz_invalid(void) endptr = NULL; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmpint(res, ==, 0xbaadf00d); + g_assert_cmphex(res, ==, 0xbaadf00d); g_assert_true(endptr == str); str = " \t "; endptr = NULL; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmpint(res, ==, 0xbaadf00d); + g_assert_cmphex(res, ==, 0xbaadf00d); g_assert_true(endptr == str); str = "crap"; endptr = NULL; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmpint(res, ==, 0xbaadf00d); + g_assert_cmphex(res, ==, 0xbaadf00d); g_assert_true(endptr == str); str = "inf"; endptr = NULL; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmpint(res, ==, 0xbaadf00d); + g_assert_cmphex(res, ==, 0xbaadf00d); g_assert_true(endptr == str); str = "NaN"; endptr = NULL; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmpint(res, ==, 0xbaadf00d); + g_assert_cmphex(res, ==, 0xbaadf00d); g_assert_true(endptr == str); /* Fractional values require scale larger than bytes */ @@ -2281,14 +2281,14 @@ static void test_qemu_strtosz_invalid(void) endptr = NULL; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmpint(res, ==, 0xbaadf00d); + g_assert_cmphex(res, ==, 0xbaadf00d); g_assert_true(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_cmphex(res, ==, 0xbaadf00d); g_assert_true(endptr == str); /* No floating point exponents */ @@ -2296,14 +2296,14 @@ static void test_qemu_strtosz_invalid(void) endptr = NULL; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmpint(res, ==, 0xbaadf00d); + g_assert_cmphex(res, ==, 0xbaadf00d); g_assert_true(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_cmphex(res, ==, 0xbaadf00d); g_assert_true(endptr == str); /* No hex fractions */ @@ -2311,7 +2311,7 @@ static void test_qemu_strtosz_invalid(void) endptr = NULL; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmpint(res, ==, 0xbaadf00d); + g_assert_cmphex(res, ==, 0xbaadf00d); g_assert_true(endptr == str); /* No suffixes */ @@ -2319,7 +2319,7 @@ static void test_qemu_strtosz_invalid(void) endptr = NULL; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmpint(res, ==, 0xbaadf00d); + g_assert_cmphex(res, ==, 0xbaadf00d); g_assert_true(endptr == str); /* No negative values */ @@ -2327,14 +2327,14 @@ static void test_qemu_strtosz_invalid(void) endptr = NULL; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmpint(res, ==, 0xbaadf00d); + g_assert_cmphex(res, ==, 0xbaadf00d); g_assert_true(endptr == str); str = "-1"; endptr = NULL; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmpint(res, ==, 0xbaadf00d); + g_assert_cmphex(res, ==, 0xbaadf00d); g_assert_true(endptr == str); } @@ -2350,65 +2350,65 @@ static void test_qemu_strtosz_trailing(void) res = 0xbaadf00d; err = qemu_strtosz_MiB(str, &endptr, &res); g_assert_cmpint(err, ==, 0); - g_assert_cmpint(res, ==, 123 * MiB); + g_assert_cmpuint(res, ==, 123 * MiB); g_assert_true(endptr == str + 3); res = 0xbaadf00d; err = qemu_strtosz(str, NULL, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmpint(res, ==, 0xbaadf00d); + g_assert_cmphex(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_cmpuint(res, ==, 1024); g_assert_true(endptr == str + 2); res = 0xbaadf00d; err = qemu_strtosz(str, NULL, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmpint(res, ==, 0xbaadf00d); + g_assert_cmphex(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_cmpuint(res, ==, 0); g_assert_true(endptr == str + 1); res = 0xbaadf00d; err = qemu_strtosz(str, NULL, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmpint(res, ==, 0xbaadf00d); + g_assert_cmphex(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_cmpuint(res, ==, 0); g_assert_true(endptr == str + 2); res = 0xbaadf00d; err = qemu_strtosz(str, NULL, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmpint(res, ==, 0xbaadf00d); + g_assert_cmphex(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_cmpuint(res, ==, 123); g_assert_true(endptr == str + 3); res = 0xbaadf00d; err = qemu_strtosz(str, NULL, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmpint(res, ==, 0xbaadf00d); + g_assert_cmphex(res, ==, 0xbaadf00d); } static void test_qemu_strtosz_erange(void) @@ -2422,14 +2422,14 @@ static void test_qemu_strtosz_erange(void) endptr = NULL; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -ERANGE); - g_assert_cmpint(res, ==, 0xbaadf00d); + g_assert_cmphex(res, ==, 0xbaadf00d); g_assert_true(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_cmphex(res, ==, 0xbaadf00d); g_assert_true(endptr == str + 3); } @@ -2445,7 +2445,7 @@ static void test_qemu_strtosz_metric(void) res = 0xbaadf00d; err = qemu_strtosz_metric(str, &endptr, &res); g_assert_cmpint(err, ==, 0); - g_assert_cmpint(res, ==, 12345000); + g_assert_cmpuint(res, ==, 12345000); g_assert_true(endptr == str + 6); str = "12.345M"; @@ -2453,7 +2453,7 @@ static void test_qemu_strtosz_metric(void) res = 0xbaadf00d; err = qemu_strtosz_metric(str, &endptr, &res); g_assert_cmpint(err, ==, 0); - g_assert_cmpint(res, ==, 12345000); + g_assert_cmpuint(res, ==, 12345000); g_assert_true(endptr == str + 7); } From patchwork Mon May 8 20:03:35 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Blake X-Patchwork-Id: 13234997 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 7BE36C7EE22 for ; Mon, 8 May 2023 20:04:31 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pw75m-0006Hx-0u; Mon, 08 May 2023 16:04:19 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pw75N-0006ET-JY for qemu-devel@nongnu.org; Mon, 08 May 2023 16:03:54 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pw75L-0007JO-10 for qemu-devel@nongnu.org; Mon, 08 May 2023 16:03:53 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1683576230; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Ej79sOGO57EYASbdhKj+1MYcJxhxOSf0nSzYRIWM6h8=; b=Ipqoh1wXldP5v2sHfQljVExbkTUpwb8rI2VG5kow6STmULLtUdKA+eEe6EROGpsIWyBsOz dv7S3FdktbzGQtT1KaMCTvFGHuvsGiIseRGUM9Ph2cfhkP/IKDjMWK6Af64ocCpMbX5jqV inyzaMYWyrDumeFtknheSrJuzUzcfKU= Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-632-MPa7zCmSPE2KgMH22tO0rw-1; Mon, 08 May 2023 16:03:47 -0400 X-MC-Unique: MPa7zCmSPE2KgMH22tO0rw-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id E1B9B3C0ED41 for ; Mon, 8 May 2023 20:03:46 +0000 (UTC) Received: from green.redhat.com (unknown [10.2.16.49]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9F8EF1121314; Mon, 8 May 2023 20:03:46 +0000 (UTC) From: Eric Blake To: qemu-devel@nongnu.org Cc: hreitz@redhat.com Subject: [PATCH 03/11] test-cutils: Test integral qemu_strto* value on failures Date: Mon, 8 May 2023 15:03:35 -0500 Message-Id: <20230508200343.791450-4-eblake@redhat.com> In-Reply-To: <20230508200343.791450-1-eblake@redhat.com> References: <20230508200343.791450-1-eblake@redhat.com> MIME-Version: 1.0 Content-type: text/plain X-Scanned-By: MIMEDefang 3.1 on 10.11.54.3 Received-SPF: pass client-ip=170.10.133.124; envelope-from=eblake@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org We are inconsistent on the contents of *value after a strto* parse failure. I found the following behaviors: - parse_uint() and parse_uint_full(), which document that *value is slammed to 0 on all EINVAL failures and 0 or UINT_MAX on ERANGE failures, and has unit tests for that (note that parse_uint requires non-NULL endptr, and does not fail with EINVAL for trailing junk) - qemu_strtosz(), which leaves *value untouched on all failures (both EINVAL and ERANGE), and has unit tests but not documentation for that - qemu_strtoi() and other integral friends, which document *value on ERANGE failures but is unspecified on EINVAL (other than implicitly by comparison to libc strto*); there, *value is untouched for NULL string, slammed to 0 on no conversion, and left at the prefix value on NULL endptr; unit tests do not consistently check the value - qemu_strtod(), which documents *value on ERANGE failures but is unspecified on EINVAL; there, *value is untouched for NULL string, slammed to 0.0 for no conversion, and left at the prefix value on NULL endptr; there are no unit tests (other than indirectly through qemu_strtosz) - qemu_strtod_finite(), which documents *value on ERANGE failures but is unspecified on EINVAL; there, *value is left at the prefix for 'inf' or 'nan' and untouched in all other cases; there are no unit tests (other than indirectly through qemu_strtosz) Upcoming patches will change behaviors for consistency, but it's best to first have more unit test coverage to see the impact of those changes. Signed-off-by: Eric Blake --- tests/unit/test-cutils.c | 58 +++++++++++++++++++++++++++++++++++----- 1 file changed, 51 insertions(+), 7 deletions(-) diff --git a/tests/unit/test-cutils.c b/tests/unit/test-cutils.c index 38bd3990207..1eeaf21ae22 100644 --- a/tests/unit/test-cutils.c +++ b/tests/unit/test-cutils.c @@ -248,6 +248,7 @@ static void test_qemu_strtoi_null(void) err = qemu_strtoi(NULL, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpint(res, ==, 999); g_assert_null(endptr); } @@ -262,6 +263,7 @@ static void test_qemu_strtoi_empty(void) err = qemu_strtoi(str, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpint(res, ==, 0); g_assert_true(endptr == str); } @@ -276,6 +278,7 @@ static void test_qemu_strtoi_whitespace(void) err = qemu_strtoi(str, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpint(res, ==, 0); g_assert_true(endptr == str); } @@ -290,6 +293,7 @@ static void test_qemu_strtoi_invalid(void) err = qemu_strtoi(str, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpint(res, ==, 0); g_assert_true(endptr == str); } @@ -473,6 +477,7 @@ static void test_qemu_strtoi_full_null(void) err = qemu_strtoi(NULL, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpint(res, ==, 999); g_assert_null(endptr); } @@ -485,6 +490,7 @@ static void test_qemu_strtoi_full_empty(void) err = qemu_strtoi(str, NULL, 0, &res); g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpint(res, ==, 0); } static void test_qemu_strtoi_full_negative(void) @@ -502,18 +508,19 @@ static void test_qemu_strtoi_full_negative(void) static void test_qemu_strtoi_full_trailing(void) { const char *str = "123xxx"; - int res; + int res = 999; int err; err = qemu_strtoi(str, NULL, 0, &res); g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpint(res, ==, 123); } static void test_qemu_strtoi_full_max(void) { char *str = g_strdup_printf("%d", INT_MAX); - int res; + int res = 999; int err; err = qemu_strtoi(str, NULL, 0, &res); @@ -548,6 +555,7 @@ static void test_qemu_strtoui_null(void) err = qemu_strtoui(NULL, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpuint(res, ==, 999); g_assert_null(endptr); } @@ -562,6 +570,7 @@ static void test_qemu_strtoui_empty(void) err = qemu_strtoui(str, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpuint(res, ==, 0); g_assert_true(endptr == str); } @@ -576,6 +585,7 @@ static void test_qemu_strtoui_whitespace(void) err = qemu_strtoui(str, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpuint(res, ==, 0); g_assert_true(endptr == str); } @@ -590,6 +600,7 @@ static void test_qemu_strtoui_invalid(void) err = qemu_strtoui(str, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpuint(res, ==, 0); g_assert_true(endptr == str); } @@ -771,6 +782,7 @@ static void test_qemu_strtoui_full_null(void) err = qemu_strtoui(NULL, NULL, 0, &res); g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpuint(res, ==, 999); } static void test_qemu_strtoui_full_empty(void) @@ -782,7 +794,9 @@ static void test_qemu_strtoui_full_empty(void) err = qemu_strtoui(str, NULL, 0, &res); g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpuint(res, ==, 0); } + static void test_qemu_strtoui_full_negative(void) { const char *str = " \t -321"; @@ -797,12 +811,13 @@ static void test_qemu_strtoui_full_negative(void) static void test_qemu_strtoui_full_trailing(void) { const char *str = "123xxx"; - unsigned int res; + unsigned int res = 999; int err; err = qemu_strtoui(str, NULL, 0, &res); g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpuint(res, ==, 123); } static void test_qemu_strtoui_full_max(void) @@ -843,6 +858,7 @@ static void test_qemu_strtol_null(void) err = qemu_strtol(NULL, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpint(res, ==, 999); g_assert_null(endptr); } @@ -857,6 +873,7 @@ static void test_qemu_strtol_empty(void) err = qemu_strtol(str, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpint(res, ==, 0); g_assert_true(endptr == str); } @@ -871,6 +888,7 @@ static void test_qemu_strtol_whitespace(void) err = qemu_strtol(str, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpint(res, ==, 0); g_assert_true(endptr == str); } @@ -885,6 +903,7 @@ static void test_qemu_strtol_invalid(void) err = qemu_strtol(str, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpint(res, ==, 0); g_assert_true(endptr == str); } @@ -1066,6 +1085,7 @@ static void test_qemu_strtol_full_null(void) err = qemu_strtol(NULL, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpint(res, ==, 999); g_assert_null(endptr); } @@ -1078,6 +1098,7 @@ static void test_qemu_strtol_full_empty(void) err = qemu_strtol(str, NULL, 0, &res); g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpint(res, ==, 0); } static void test_qemu_strtol_full_negative(void) @@ -1095,18 +1116,19 @@ static void test_qemu_strtol_full_negative(void) static void test_qemu_strtol_full_trailing(void) { const char *str = "123xxx"; - long res; + long res = 999; int err; err = qemu_strtol(str, NULL, 0, &res); g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpint(res, ==, 123); } static void test_qemu_strtol_full_max(void) { char *str = g_strdup_printf("%ld", LONG_MAX); - long res; + long res = 999; int err; err = qemu_strtol(str, NULL, 0, &res); @@ -1141,6 +1163,7 @@ static void test_qemu_strtoul_null(void) err = qemu_strtoul(NULL, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpuint(res, ==, 999); g_assert_null(endptr); } @@ -1155,6 +1178,7 @@ static void test_qemu_strtoul_empty(void) err = qemu_strtoul(str, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpuint(res, ==, 0); g_assert_true(endptr == str); } @@ -1169,6 +1193,7 @@ static void test_qemu_strtoul_whitespace(void) err = qemu_strtoul(str, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpuint(res, ==, 0); g_assert_true(endptr == str); } @@ -1183,6 +1208,7 @@ static void test_qemu_strtoul_invalid(void) err = qemu_strtoul(str, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpuint(res, ==, 0); g_assert_true(endptr == str); } @@ -1362,6 +1388,7 @@ static void test_qemu_strtoul_full_null(void) err = qemu_strtoul(NULL, NULL, 0, &res); g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpuint(res, ==, 999); } static void test_qemu_strtoul_full_empty(void) @@ -1373,7 +1400,9 @@ static void test_qemu_strtoul_full_empty(void) err = qemu_strtoul(str, NULL, 0, &res); g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpuint(res, ==, 0); } + static void test_qemu_strtoul_full_negative(void) { const char *str = " \t -321"; @@ -1388,12 +1417,13 @@ static void test_qemu_strtoul_full_negative(void) static void test_qemu_strtoul_full_trailing(void) { const char *str = "123xxx"; - unsigned long res; + unsigned long res = 999; int err; err = qemu_strtoul(str, NULL, 0, &res); g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpuint(res, ==, 123); } static void test_qemu_strtoul_full_max(void) @@ -1434,6 +1464,7 @@ static void test_qemu_strtoi64_null(void) err = qemu_strtoi64(NULL, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpint(res, ==, 999); g_assert_null(endptr); } @@ -1448,6 +1479,7 @@ static void test_qemu_strtoi64_empty(void) err = qemu_strtoi64(str, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpint(res, ==, 0); g_assert_true(endptr == str); } @@ -1462,6 +1494,7 @@ static void test_qemu_strtoi64_whitespace(void) err = qemu_strtoi64(str, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpint(res, ==, 0); g_assert_true(endptr == str); } @@ -1476,6 +1509,7 @@ static void test_qemu_strtoi64_invalid(void) err = qemu_strtoi64(str, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpint(res, ==, 0); g_assert_true(endptr == str); } @@ -1655,6 +1689,7 @@ static void test_qemu_strtoi64_full_null(void) err = qemu_strtoi64(NULL, NULL, 0, &res); g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpint(res, ==, 999); } static void test_qemu_strtoi64_full_empty(void) @@ -1666,6 +1701,7 @@ static void test_qemu_strtoi64_full_empty(void) err = qemu_strtoi64(str, NULL, 0, &res); g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpint(res, ==, 0); } static void test_qemu_strtoi64_full_negative(void) @@ -1689,13 +1725,14 @@ static void test_qemu_strtoi64_full_trailing(void) err = qemu_strtoi64(str, NULL, 0, &res); g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpint(res, ==, 123); } static void test_qemu_strtoi64_full_max(void) { char *str = g_strdup_printf("%lld", LLONG_MAX); - int64_t res; + int64_t res = 999; int err; err = qemu_strtoi64(str, NULL, 0, &res); @@ -1730,6 +1767,7 @@ static void test_qemu_strtou64_null(void) err = qemu_strtou64(NULL, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpuint(res, ==, 999); g_assert_null(endptr); } @@ -1744,6 +1782,7 @@ static void test_qemu_strtou64_empty(void) err = qemu_strtou64(str, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpuint(res, ==, 0); g_assert_true(endptr == str); } @@ -1758,6 +1797,7 @@ static void test_qemu_strtou64_whitespace(void) err = qemu_strtou64(str, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpuint(res, ==, 0); g_assert_true(endptr == str); } @@ -1772,6 +1812,7 @@ static void test_qemu_strtou64_invalid(void) err = qemu_strtou64(str, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpuint(res, ==, 0); g_assert_true(endptr == str); } @@ -1951,6 +1992,7 @@ static void test_qemu_strtou64_full_null(void) err = qemu_strtou64(NULL, NULL, 0, &res); g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpuint(res, ==, 999); } static void test_qemu_strtou64_full_empty(void) @@ -1962,6 +2004,7 @@ static void test_qemu_strtou64_full_empty(void) err = qemu_strtou64(str, NULL, 0, &res); g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpuint(res, ==, 0); } static void test_qemu_strtou64_full_negative(void) @@ -1985,6 +2028,7 @@ static void test_qemu_strtou64_full_trailing(void) err = qemu_strtou64(str, NULL, 0, &res); g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpuint(res, ==, 18446744073709551614ULL); } static void test_qemu_strtou64_full_max(void) From patchwork Mon May 8 20:03:36 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Blake X-Patchwork-Id: 13235008 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 76261C77B7F for ; Mon, 8 May 2023 20:06:57 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pw75o-0006Il-Kx; Mon, 08 May 2023 16:04:20 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pw75N-0006ER-9c for qemu-devel@nongnu.org; Mon, 08 May 2023 16:03:54 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pw75J-0007J8-TN for qemu-devel@nongnu.org; Mon, 08 May 2023 16:03:53 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1683576229; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=BEYud4RTvD3ilmxWxMAjHFYX+Sekfi1DuUN+39KGiMQ=; b=iZxZJQvvONvyrCDs5mBrKOm49gdgIqshhh+UJD3Gd9Fz4ml3zIFO2OD8DhTJchrj0UOxFu Zyb1LQF4h8H8ieYnG8CoG1LwxVDzuX10HyckGcWgrMbVdGE7sptC53vdFj8Gv7+7MWkcsy P8llhnuN74wGca48o79krWZU2aqFoAg= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-539-o9Nv0vL7PGOfqmV5j4ItzQ-1; Mon, 08 May 2023 16:03:47 -0400 X-MC-Unique: o9Nv0vL7PGOfqmV5j4ItzQ-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 5BED084AF2F for ; Mon, 8 May 2023 20:03:47 +0000 (UTC) Received: from green.redhat.com (unknown [10.2.16.49]) by smtp.corp.redhat.com (Postfix) with ESMTP id 190B31121314; Mon, 8 May 2023 20:03:47 +0000 (UTC) From: Eric Blake To: qemu-devel@nongnu.org Cc: hreitz@redhat.com Subject: [PATCH 04/11] test-cutils: Add coverage of qemu_strtod Date: Mon, 8 May 2023 15:03:36 -0500 Message-Id: <20230508200343.791450-5-eblake@redhat.com> In-Reply-To: <20230508200343.791450-1-eblake@redhat.com> References: <20230508200343.791450-1-eblake@redhat.com> MIME-Version: 1.0 Content-type: text/plain X-Scanned-By: MIMEDefang 3.1 on 10.11.54.3 Received-SPF: pass client-ip=170.10.129.124; envelope-from=eblake@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Plenty more corner cases of strtod proper, but this covers the bulk of what our wrappers do. In particular, it demonstrates the difference on when *value is left uninitialized, which an upcoming patch will normalize. Signed-off-by: Eric Blake --- tests/unit/test-cutils.c | 435 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 435 insertions(+) diff --git a/tests/unit/test-cutils.c b/tests/unit/test-cutils.c index 1eeaf21ae22..4c096c6fc70 100644 --- a/tests/unit/test-cutils.c +++ b/tests/unit/test-cutils.c @@ -25,6 +25,8 @@ * THE SOFTWARE. */ +#include + #include "qemu/osdep.h" #include "qemu/cutils.h" #include "qemu/units.h" @@ -2044,6 +2046,414 @@ static void test_qemu_strtou64_full_max(void) g_free(str); } +static void test_qemu_strtod_simple(void) +{ + const char *str; + const char *endptr; + int err; + double res; + + /* no radix or exponent */ + str = "1"; + endptr = NULL; + res = 999; + err = qemu_strtod(str, &endptr, &res); + g_assert_cmpint(err, ==, 0); + g_assert_cmpfloat(res, ==, 1.0); + g_assert_true(endptr == str + 1); + + /* leading space and sign */ + str = " -0.0"; + endptr = NULL; + res = 999; + err = qemu_strtod(str, &endptr, &res); + g_assert_cmpint(err, ==, 0); + g_assert_cmpfloat(res, ==, -0.0); + g_assert_true(signbit(res)); + g_assert_true(endptr == str + 5); + + /* fraction only */ + str = "+.5"; + endptr = NULL; + res = 999; + err = qemu_strtod(str, &endptr, &res); + g_assert_cmpint(err, ==, 0); + g_assert_cmpfloat(res, ==, 0.5); + g_assert_true(endptr == str + 3); + + /* exponent */ + str = "1.e+1"; + endptr = NULL; + res = 999; + err = qemu_strtod(str, &endptr, &res); + g_assert_cmpint(err, ==, 0); + g_assert_cmpfloat(res, ==, 10.0); + g_assert_true(endptr == str + 5); +} + +static void test_qemu_strtod_einval(void) +{ + const char *str; + const char *endptr; + int err; + double res; + + /* empty */ + str = ""; + endptr = NULL; + res = 999; + err = qemu_strtod(str, &endptr, &res); + g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpfloat(res, ==, 0.0); + g_assert_true(endptr == str); + + /* NULL */ + str = NULL; + endptr = "random"; + res = 999; + err = qemu_strtod(str, &endptr, &res); + g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpfloat(res, ==, 999.0); + g_assert_null(endptr); + + /* not recognizable */ + str = " junk"; + endptr = NULL; + res = 999; + err = qemu_strtod(str, &endptr, &res); + g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpfloat(res, ==, 0.0); + g_assert_true(endptr == str); +} + +static void test_qemu_strtod_erange(void) +{ + const char *str; + const char *endptr; + int err; + double res; + + /* overflow */ + str = "9e999"; + endptr = NULL; + res = 999; + err = qemu_strtod(str, &endptr, &res); + g_assert_cmpint(err, ==, -ERANGE); + g_assert_cmpfloat(res, ==, HUGE_VAL); + g_assert_true(endptr == str + 5); + + str = "-9e+999"; + endptr = NULL; + res = 999; + err = qemu_strtod(str, &endptr, &res); + g_assert_cmpint(err, ==, -ERANGE); + g_assert_cmpfloat(res, ==, -HUGE_VAL); + g_assert_true(endptr == str + 7); + + /* underflow */ + str = "-9e-999"; + endptr = NULL; + res = 999; + err = qemu_strtod(str, &endptr, &res); + g_assert_cmpint(err, ==, -ERANGE); + g_assert_cmpfloat(res, >=, -DBL_MIN); + g_assert_cmpfloat(res, <=, -0.0); + g_assert_true(signbit(res)); + g_assert_true(endptr == str + 7); +} + +static void test_qemu_strtod_nonfinite(void) +{ + const char *str; + const char *endptr; + int err; + double res; + + /* infinity */ + str = "inf"; + endptr = NULL; + res = 999; + err = qemu_strtod(str, &endptr, &res); + g_assert_cmpint(err, ==, 0); + g_assert_true(isinf(res)); + g_assert_false(signbit(res)); + g_assert_true(endptr == str + 3); + + str = "-infinity"; + endptr = NULL; + res = 999; + err = qemu_strtod(str, &endptr, &res); + g_assert_cmpint(err, ==, 0); + g_assert_true(isinf(res)); + g_assert_true(signbit(res)); + g_assert_true(endptr == str + 9); + + /* not a number */ + str = " NaN"; + endptr = NULL; + res = 999; + err = qemu_strtod(str, &endptr, &res); + g_assert_cmpint(err, ==, 0); + g_assert_true(isnan(res)); + g_assert_true(endptr == str + 4); +} + +static void test_qemu_strtod_trailing(void) +{ + const char *str; + const char *endptr; + int err; + double res; + + /* trailing whitespace */ + str = "1. "; + endptr = NULL; + res = 999; + err = qemu_strtod(str, &endptr, &res); + g_assert_cmpint(err, ==, 0); + g_assert_cmpfloat(res, ==, 1.0); + g_assert_true(endptr == str + 2); + + endptr = NULL; + res = 999; + err = qemu_strtod(str, NULL, &res); + g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpfloat(res, ==, 1.0); + + /* trailing e is not an exponent */ + str = ".5e"; + endptr = NULL; + res = 999; + err = qemu_strtod(str, &endptr, &res); + g_assert_cmpint(err, ==, 0); + g_assert_cmpfloat(res, ==, 0.5); + g_assert_true(endptr == str + 2); + + endptr = NULL; + res = 999; + err = qemu_strtod(str, NULL, &res); + g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpfloat(res, ==, 0.5); + + /* trailing ( not part of long NaN */ + str = "nan("; + endptr = NULL; + res = 999; + err = qemu_strtod(str, &endptr, &res); + g_assert_cmpint(err, ==, 0); + g_assert_true(isnan(res)); + g_assert_true(endptr == str + 3); + + endptr = NULL; + res = 999; + err = qemu_strtod(str, NULL, &res); + g_assert_cmpint(err, ==, -EINVAL); + g_assert_true(isnan(res)); +} + +static void test_qemu_strtod_finite_simple(void) +{ + const char *str; + const char *endptr; + int err; + double res; + + /* no radix or exponent */ + str = "1"; + endptr = NULL; + res = 999; + err = qemu_strtod_finite(str, &endptr, &res); + g_assert_cmpint(err, ==, 0); + g_assert_cmpfloat(res, ==, 1.0); + g_assert_true(endptr == str + 1); + + /* leading space and sign */ + str = " -0.0"; + endptr = NULL; + res = 999; + err = qemu_strtod_finite(str, &endptr, &res); + g_assert_cmpint(err, ==, 0); + g_assert_cmpfloat(res, ==, -0.0); + g_assert_true(signbit(res)); + g_assert_true(endptr == str + 5); + + /* fraction only */ + str = "+.5"; + endptr = NULL; + res = 999; + err = qemu_strtod_finite(str, &endptr, &res); + g_assert_cmpint(err, ==, 0); + g_assert_cmpfloat(res, ==, 0.5); + g_assert_true(endptr == str + 3); + + /* exponent */ + str = "1.e+1"; + endptr = NULL; + res = 999; + err = qemu_strtod_finite(str, &endptr, &res); + g_assert_cmpint(err, ==, 0); + g_assert_cmpfloat(res, ==, 10.0); + g_assert_true(endptr == str + 5); +} + +static void test_qemu_strtod_finite_einval(void) +{ + const char *str; + const char *endptr; + int err; + double res; + + /* empty */ + str = ""; + endptr = NULL; + res = 999; + err = qemu_strtod_finite(str, &endptr, &res); + g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpfloat(res, ==, 999.0); + g_assert_true(endptr == str); + + /* NULL */ + str = NULL; + endptr = "random"; + res = 999; + err = qemu_strtod_finite(str, &endptr, &res); + g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpfloat(res, ==, 999.0); + g_assert_null(endptr); + + /* not recognizable */ + str = " junk"; + endptr = NULL; + res = 999; + err = qemu_strtod_finite(str, &endptr, &res); + g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpfloat(res, ==, 999.0); + g_assert_true(endptr == str); +} + +static void test_qemu_strtod_finite_erange(void) +{ + const char *str; + const char *endptr; + int err; + double res; + + /* overflow */ + str = "9e999"; + endptr = NULL; + res = 999; + err = qemu_strtod_finite(str, &endptr, &res); + g_assert_cmpint(err, ==, -ERANGE); + g_assert_cmpfloat(res, ==, HUGE_VAL); + g_assert_true(endptr == str + 5); + + str = "-9e+999"; + endptr = NULL; + res = 999; + err = qemu_strtod_finite(str, &endptr, &res); + g_assert_cmpint(err, ==, -ERANGE); + g_assert_cmpfloat(res, ==, -HUGE_VAL); + g_assert_true(endptr == str + 7); + + /* underflow */ + str = "-9e-999"; + endptr = NULL; + res = 999; + err = qemu_strtod_finite(str, &endptr, &res); + g_assert_cmpint(err, ==, -ERANGE); + g_assert_cmpfloat(res, >=, -DBL_MIN); + g_assert_cmpfloat(res, <=, -0.0); + g_assert_true(signbit(res)); + g_assert_true(endptr == str + 7); +} + +static void test_qemu_strtod_finite_nonfinite(void) +{ + const char *str; + const char *endptr; + int err; + double res; + + /* infinity */ + str = "inf"; + endptr = NULL; + res = 999; + err = qemu_strtod_finite(str, &endptr, &res); + g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpfloat(res, ==, 999.0); + g_assert_true(endptr == str); + + str = "-infinity"; + endptr = NULL; + res = 999; + err = qemu_strtod_finite(str, &endptr, &res); + g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpfloat(res, ==, 999.0); + g_assert_true(endptr == str); + + /* not a number */ + str = " NaN"; + endptr = NULL; + res = 999; + err = qemu_strtod_finite(str, &endptr, &res); + g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpfloat(res, ==, 999.0); + g_assert_true(endptr == str); +} + +static void test_qemu_strtod_finite_trailing(void) +{ + const char *str; + const char *endptr; + int err; + double res; + + /* trailing whitespace */ + str = "1. "; + endptr = NULL; + res = 999; + err = qemu_strtod_finite(str, &endptr, &res); + g_assert_cmpint(err, ==, 0); + g_assert_cmpfloat(res, ==, 1.0); + g_assert_true(endptr == str + 2); + + endptr = NULL; + res = 999; + err = qemu_strtod_finite(str, NULL, &res); + g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpfloat(res, ==, 999.0); + + /* trailing e is not an exponent */ + str = ".5e"; + endptr = NULL; + res = 999; + err = qemu_strtod_finite(str, &endptr, &res); + g_assert_cmpint(err, ==, 0); + g_assert_cmpfloat(res, ==, 0.5); + g_assert_true(endptr == str + 2); + + endptr = NULL; + res = 999; + err = qemu_strtod_finite(str, NULL, &res); + g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpfloat(res, ==, 999.0); + + /* trailing ( not part of long NaN */ + str = "nan("; + endptr = NULL; + res = 999; + err = qemu_strtod_finite(str, &endptr, &res); + g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpfloat(res, ==, 999.0); + g_assert_true(endptr == str); + + endptr = NULL; + res = 999; + err = qemu_strtod_finite(str, NULL, &res); + g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpfloat(res, ==, 999.0); +} + static void test_qemu_strtosz_simple(void) { const char *str; @@ -2833,6 +3243,31 @@ int main(int argc, char **argv) g_test_add_func("/cutils/qemu_strtou64_full/max", test_qemu_strtou64_full_max); + /* qemu_strtod() tests */ + g_test_add_func("/cutils/qemu_strtod/simple", + test_qemu_strtod_simple); + g_test_add_func("/cutils/qemu_strtod/einval", + test_qemu_strtod_einval); + g_test_add_func("/cutils/qemu_strtod/erange", + test_qemu_strtod_erange); + g_test_add_func("/cutils/qemu_strtod/nonfinite", + test_qemu_strtod_nonfinite); + g_test_add_func("/cutils/qemu_strtod/trailing", + test_qemu_strtod_trailing); + + /* qemu_strtod_finite() tests */ + g_test_add_func("/cutils/qemu_strtod_finite/simple", + test_qemu_strtod_finite_simple); + g_test_add_func("/cutils/qemu_strtod_finite/einval", + test_qemu_strtod_finite_einval); + g_test_add_func("/cutils/qemu_strtod_finite/erange", + test_qemu_strtod_finite_erange); + g_test_add_func("/cutils/qemu_strtod_finite/nonfinite", + test_qemu_strtod_finite_nonfinite); + g_test_add_func("/cutils/qemu_strtod_finite/trailing", + test_qemu_strtod_finite_trailing); + + /* qemu_strtosz() tests */ g_test_add_func("/cutils/strtosz/simple", test_qemu_strtosz_simple); g_test_add_func("/cutils/strtosz/hex", From patchwork Mon May 8 20:03:37 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Blake X-Patchwork-Id: 13235003 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 16F6DC77B7F for ; Mon, 8 May 2023 20:05:41 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pw75m-0006Hv-0E; Mon, 08 May 2023 16:04:19 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pw75O-0006EW-Ra for qemu-devel@nongnu.org; Mon, 08 May 2023 16:03:58 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pw75M-0007JZ-Rh for qemu-devel@nongnu.org; Mon, 08 May 2023 16:03:54 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1683576231; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=8qXnzf5wAY7QoNKSKgifx0SiYIqzbqZVhzu5JLe1iOc=; b=Rk7IomsX8j1NYg4zApBln8MGEcnP//PYpe7N7YHfojSQDOAAZEXsQkpq8BlAsjPzzY1Aaf E+aOzctW76nqmsa9P2nap93ZFcUz87IGVGUoGcenrME+O45tqfdo6/jS5LoU9HXQ5Z2iBc mi1YBjwOm86Cv0JkmpvxNSK+Sr+uWpA= Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-670--g1FMxQ6Pb6OobCx0cskEg-1; Mon, 08 May 2023 16:03:48 -0400 X-MC-Unique: -g1FMxQ6Pb6OobCx0cskEg-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id C6FFC1C05199 for ; Mon, 8 May 2023 20:03:47 +0000 (UTC) Received: from green.redhat.com (unknown [10.2.16.49]) by smtp.corp.redhat.com (Postfix) with ESMTP id 839601121314; Mon, 8 May 2023 20:03:47 +0000 (UTC) From: Eric Blake To: qemu-devel@nongnu.org Cc: hreitz@redhat.com Subject: [PATCH 05/11] test-cutils: Prepare for upcoming semantic change in qemu_strtosz Date: Mon, 8 May 2023 15:03:37 -0500 Message-Id: <20230508200343.791450-6-eblake@redhat.com> In-Reply-To: <20230508200343.791450-1-eblake@redhat.com> References: <20230508200343.791450-1-eblake@redhat.com> MIME-Version: 1.0 Content-type: text/plain X-Scanned-By: MIMEDefang 3.1 on 10.11.54.3 Received-SPF: pass client-ip=170.10.133.124; envelope-from=eblake@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org A quick search for 'qemu_strtosz' in the code base shows that outside of the testsuite, the ONLY place that passes a non-NULL pointer to @endptr of any variant of a size parser is in hmp.c (the 'o' parser of monitor_parse_arguments), and that particular caller warns of "extraneous characters at the end of line" unless the trailing bytes are purely whitespace. Thus, it makes no semantic difference at the high level whether we parse "1.5e1k" as "1" + ".5e1" + "k" (an attempt to use scientific notation in strtod with a scaling suffix of 'k' with no trailing junk, but which qemu_strtosz says should fail with EINVAL), or as "1.5e" + "1k" (a valid size with scaling suffix of 'e' for exabytes, followed by two junk bytes) - either way, any user passing such a string will get an error message about a parse failure. However, an upcoming patch to qemu_strtosz will fix other corner case bugs in handling the fractional portion of a size, and in doing so, it is easier to declare that qemu_strtosz() itself stops parsing at the first 'e' rather than blindly consuming whatever strtod() will recognize. Once that is fixed, the difference will be visible at the low level (getting a valid parse with trailing garbage when @endptr is non-NULL, while continuing to get -EINVAL when @endptr is NULL); this is easier to demonstrate by moving the affected strings from test_qemu_strtosz_invalid() (which declares them as always -EINVAL) to test_qemu_strtosz_trailing() (where @endptr affects behavior, for now with FIXME comments). Note that a similar argument could be made for having "0x1.5" or "0x1M" parse as 0x1 with ".5" or "M" as trailing junk, instead of blindly treating it as -EINVAL; however, as these cases do not suffer from the same problems as floating point, they are not worth changing at this time. Signed-off-by: Eric Blake --- tests/unit/test-cutils.c | 42 ++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/tests/unit/test-cutils.c b/tests/unit/test-cutils.c index 4c096c6fc70..afae2ee5331 100644 --- a/tests/unit/test-cutils.c +++ b/tests/unit/test-cutils.c @@ -2745,21 +2745,6 @@ static void test_qemu_strtosz_invalid(void) g_assert_cmphex(res, ==, 0xbaadf00d); g_assert_true(endptr == str); - /* No floating point exponents */ - str = "1.5e1k"; - endptr = NULL; - err = qemu_strtosz(str, &endptr, &res); - g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmphex(res, ==, 0xbaadf00d); - g_assert_true(endptr == str); - - str = "1.5E+0k"; - endptr = NULL; - err = qemu_strtosz(str, &endptr, &res); - g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmphex(res, ==, 0xbaadf00d); - g_assert_true(endptr == str); - /* No hex fractions */ str = "0x1.8k"; endptr = NULL; @@ -2863,6 +2848,33 @@ static void test_qemu_strtosz_trailing(void) err = qemu_strtosz(str, NULL, &res); g_assert_cmpint(err, ==, -EINVAL); g_assert_cmphex(res, ==, 0xbaadf00d); + + /* FIXME should stop parse after 'e'. No floating point exponents */ + str = "1.5e1k"; + endptr = NULL; + res = 0xbaadf00d; + err = qemu_strtosz(str, &endptr, &res); + g_assert_cmpint(err, ==, -EINVAL /* FIXME 0 */); + g_assert_cmphex(res, ==, 0xbaadf00d /* FIXME EiB * 1.5 */); + g_assert_true(endptr == str /* FIXME + 4 */); + + res = 0xbaadf00d; + err = qemu_strtosz(str, NULL, &res); + g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpint(res, ==, 0xbaadf00d); + + str = "1.5E+0k"; + endptr = NULL; + res = 0xbaadf00d; + err = qemu_strtosz(str, &endptr, &res); + g_assert_cmpint(err, ==, -EINVAL /* FIXME 0 */); + g_assert_cmphex(res, ==, 0xbaadf00d /* FIXME EiB * 1.5 */); + g_assert_true(endptr == str /* FIXME + 4 */); + + res = 0xbaadf00d; + err = qemu_strtosz(str, NULL, &res); + g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmphex(res, ==, 0xbaadf00d); } static void test_qemu_strtosz_erange(void) From patchwork Mon May 8 20:03:38 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Blake X-Patchwork-Id: 13235004 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 508DCC7EE22 for ; Mon, 8 May 2023 20:05:53 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pw75l-0006HY-LQ; Mon, 08 May 2023 16:04:17 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pw75T-0006Ei-6s for qemu-devel@nongnu.org; Mon, 08 May 2023 16:04:00 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pw75O-0007Kc-Ve for qemu-devel@nongnu.org; Mon, 08 May 2023 16:03:57 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1683576234; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=qp/JKhOleLZTCNgS4yxWd9K5WDKme5TPewUS1v6PyqA=; b=hlj8oyOzyErILaf5hsOJTdyKI2obNZ/RpHCcKVy5HZ9iynJSKGeY+WdxI7T6U41AqcC8BE xwqjijcmwiBP7gRHCoBo4tnuaPTXF7ERWeEB8DdK7QR7DkyykZVIzkZNFDE3keEQNKR9b+ JdulAzuusu0TPk9O1uewIl2XQHbh364= Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-46-OFcttnTxO3mC-yCIWUvKvg-1; Mon, 08 May 2023 16:03:48 -0400 X-MC-Unique: OFcttnTxO3mC-yCIWUvKvg-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 3F8E41C0513E for ; Mon, 8 May 2023 20:03:48 +0000 (UTC) Received: from green.redhat.com (unknown [10.2.16.49]) by smtp.corp.redhat.com (Postfix) with ESMTP id F0BF31121314; Mon, 8 May 2023 20:03:47 +0000 (UTC) From: Eric Blake To: qemu-devel@nongnu.org Cc: hreitz@redhat.com Subject: [PATCH 06/11] test-cutils: Add more coverage to qemu_strtosz Date: Mon, 8 May 2023 15:03:38 -0500 Message-Id: <20230508200343.791450-7-eblake@redhat.com> In-Reply-To: <20230508200343.791450-1-eblake@redhat.com> References: <20230508200343.791450-1-eblake@redhat.com> MIME-Version: 1.0 Content-type: text/plain X-Scanned-By: MIMEDefang 3.1 on 10.11.54.3 Received-SPF: pass client-ip=170.10.133.124; envelope-from=eblake@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Add some more strings that the user might send our way. In particular, some of these additions include FIXME comments showing where our parser doesn't quite behave the way we want. Signed-off-by: Eric Blake --- tests/unit/test-cutils.c | 226 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 215 insertions(+), 11 deletions(-) diff --git a/tests/unit/test-cutils.c b/tests/unit/test-cutils.c index afae2ee5331..9fa6fb042e8 100644 --- a/tests/unit/test-cutils.c +++ b/tests/unit/test-cutils.c @@ -2478,14 +2478,14 @@ static void test_qemu_strtosz_simple(void) g_assert_cmpuint(res, ==, 8); g_assert_true(endptr == str + 2); - /* Leading space is ignored */ - str = " 12345"; + /* Leading space and + are ignored */ + str = " +12345"; endptr = str; res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, 0); g_assert_cmpuint(res, ==, 12345); - g_assert_true(endptr == str + 6); + g_assert_true(endptr == str + 7); res = 0xbaadf00d; err = qemu_strtosz(str, NULL, &res); @@ -2564,13 +2564,13 @@ static void test_qemu_strtosz_hex(void) g_assert_cmpuint(res, ==, 171); g_assert_true(endptr == str + 4); - str = "0xae"; + str = " +0xae"; endptr = str; res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, 0); g_assert_cmpuint(res, ==, 174); - g_assert_true(endptr == str + 4); + g_assert_true(endptr == str + 6); } static void test_qemu_strtosz_units(void) @@ -2669,14 +2669,23 @@ static void test_qemu_strtosz_float(void) g_assert_cmpuint(res, ==, 1); g_assert_true(endptr == str + 4); - /* An empty fraction is tolerated */ - str = "1.k"; + /* An empty fraction tail is tolerated */ + str = " 1.k"; endptr = str; res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, 0); g_assert_cmpuint(res, ==, 1024); - g_assert_true(endptr == str + 3); + g_assert_true(endptr == str + 4); + + /* FIXME An empty fraction head should be tolerated */ + str = " .5k"; + endptr = str; + res = 0xbaadf00d; + err = qemu_strtosz(str, &endptr, &res); + g_assert_cmpint(err, ==, -EINVAL /* FIXME 0 */); + g_assert_cmpuint(res, ==, 0xbaadf00d /* FIXME 512 */); + g_assert_true(endptr == str /* FIXME + 4 */); /* For convenience, we permit values that are not byte-exact */ str = "12.345M"; @@ -2686,6 +2695,32 @@ static void test_qemu_strtosz_float(void) g_assert_cmpint(err, ==, 0); g_assert_cmpuint(res, ==, (uint64_t) (12.345 * MiB + 0.5)); g_assert_true(endptr == str + 7); + + /* FIXME Fraction tail should round correctly */ + str = "1.9999999999999999999999999999999999999999999999999999k"; + endptr = str; + res = 0xbaadf00d; + err = qemu_strtosz(str, &endptr, &res); + g_assert_cmpint(err, ==, 0); + g_assert_cmpint(res, ==, 1024 /* FIXME 2048 */); + g_assert_true(endptr == str + 55); + + /* FIXME ERANGE underflow in the fraction tail should not matter for 'k' */ + str = "1." + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "1k"; + endptr = str; + res = 0xbaadf00d; + err = qemu_strtosz(str, &endptr, &res); + g_assert_cmpint(err, ==, 0); + g_assert_cmpuint(res, ==, 1 /* FIXME 1024 */); + g_assert_true(endptr == str + 354); } static void test_qemu_strtosz_invalid(void) @@ -2693,10 +2728,20 @@ static void test_qemu_strtosz_invalid(void) const char *str; const char *endptr; int err; - uint64_t res = 0xbaadf00d; + uint64_t res; + + /* Must parse at least one digit */ + str = NULL; + endptr = "somewhere"; + res = 0xbaadf00d; + err = qemu_strtosz(str, &endptr, &res); + g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmphex(res, ==, 0xbaadf00d); + g_assert_null(endptr); str = ""; endptr = NULL; + res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); g_assert_cmphex(res, ==, 0xbaadf00d); @@ -2704,13 +2749,30 @@ static void test_qemu_strtosz_invalid(void) str = " \t "; endptr = NULL; + res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); g_assert_cmphex(res, ==, 0xbaadf00d); g_assert_true(endptr == str); + str = "."; + endptr = NULL; + res = 0xbaadf00d; + err = qemu_strtosz(str, &endptr, &res); + g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmphex(res, ==, 0xbaadf00d); + g_assert(endptr == str); + + str = " ."; + endptr = NULL; + err = qemu_strtosz(str, &endptr, &res); + g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmphex(res, ==, 0xbaadf00d); + g_assert(endptr == str); + str = "crap"; endptr = NULL; + res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); g_assert_cmphex(res, ==, 0xbaadf00d); @@ -2718,6 +2780,7 @@ static void test_qemu_strtosz_invalid(void) str = "inf"; endptr = NULL; + res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); g_assert_cmphex(res, ==, 0xbaadf00d); @@ -2725,6 +2788,7 @@ static void test_qemu_strtosz_invalid(void) str = "NaN"; endptr = NULL; + res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); g_assert_cmphex(res, ==, 0xbaadf00d); @@ -2733,6 +2797,7 @@ static void test_qemu_strtosz_invalid(void) /* Fractional values require scale larger than bytes */ str = "1.1B"; endptr = NULL; + res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); g_assert_cmphex(res, ==, 0xbaadf00d); @@ -2740,14 +2805,42 @@ static void test_qemu_strtosz_invalid(void) str = "1.1"; endptr = NULL; + res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); g_assert_cmphex(res, ==, 0xbaadf00d); g_assert_true(endptr == str); + /* FIXME Fraction tail can cause ERANGE overflow */ + str = "15.9999999999999999999999999999999999999999999999999999E"; + endptr = str; + res = 0xbaadf00d; + err = qemu_strtosz(str, &endptr, &res); + g_assert_cmpint(err, ==, 0 /* FIXME -ERANGE */); + g_assert_cmpuint(res, ==, 15ULL * EiB /* FIXME 0xbaadf00d */); + g_assert_true(endptr == str + 56 /* FIXME str */); + + /* FIXME ERANGE underflow in the fraction tail should matter for 'B' */ + str = "1." + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000" + "1B"; + endptr = str; + res = 0xbaadf00d; + err = qemu_strtosz(str, &endptr, &res); + g_assert_cmpint(err, ==, 0 /* FIXME -EINVAL */); + g_assert_cmpuint(res, ==, 1 /* FIXME 0xbaadf00d */); + g_assert_true(endptr == str + 354 /* FIXME str */); + /* No hex fractions */ str = "0x1.8k"; endptr = NULL; + res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); g_assert_cmphex(res, ==, 0xbaadf00d); @@ -2756,14 +2849,24 @@ static void test_qemu_strtosz_invalid(void) /* No suffixes */ str = "0x18M"; endptr = NULL; + res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); g_assert_cmphex(res, ==, 0xbaadf00d); g_assert_true(endptr == str); + str = "0x1p1"; + endptr = NULL; + res = 0xbaadf00d; + err = qemu_strtosz(str, &endptr, &res); + g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmphex(res, ==, 0xbaadf00d); + g_assert(endptr == str); + /* No negative values */ - str = "-0"; + str = " -0"; endptr = NULL; + res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); g_assert_cmphex(res, ==, 0xbaadf00d); @@ -2771,10 +2874,28 @@ static void test_qemu_strtosz_invalid(void) str = "-1"; endptr = NULL; + res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); g_assert_cmphex(res, ==, 0xbaadf00d); g_assert_true(endptr == str); + + str = "-.0k"; + endptr = NULL; + res = 0xbaadf00d; + err = qemu_strtosz(str, &endptr, &res); + g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmphex(res, ==, 0xbaadf00d); + g_assert_true(endptr == str); + + /* Too many decimals */ + str = "1.1.k"; + endptr = NULL; + res = 0xbaadf00d; + err = qemu_strtosz(str, &endptr, &res); + g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmphex(res, ==, 0xbaadf00d); + g_assert(endptr == str); } static void test_qemu_strtosz_trailing(void) @@ -2784,6 +2905,21 @@ static void test_qemu_strtosz_trailing(void) int err; uint64_t res; + /* Trailing whitespace */ + str = "1k "; + endptr = NULL; + res = 0xbaadf00d; + err = qemu_strtosz(str, &endptr, &res); + g_assert_cmpint(err, ==, 0); + g_assert_cmpuint(res, ==, 1024); + g_assert(endptr == str + 2); + + res = 0xbaadf00d; + err = qemu_strtosz(str, NULL, &res); + g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmphex(res, ==, 0xbaadf00d); + + /* Unknown suffix */ str = "123xxx"; endptr = NULL; res = 0xbaadf00d; @@ -2797,6 +2933,7 @@ static void test_qemu_strtosz_trailing(void) g_assert_cmpint(err, ==, -EINVAL); g_assert_cmphex(res, ==, 0xbaadf00d); + /* Junk after one-byte suffix */ str = "1kiB"; endptr = NULL; res = 0xbaadf00d; @@ -2810,6 +2947,7 @@ static void test_qemu_strtosz_trailing(void) g_assert_cmpint(err, ==, -EINVAL); g_assert_cmphex(res, ==, 0xbaadf00d); + /* Incomplete hex is an unknown suffix */ str = "0x"; endptr = NULL; res = 0xbaadf00d; @@ -2823,6 +2961,7 @@ static void test_qemu_strtosz_trailing(void) g_assert_cmpint(err, ==, -EINVAL); g_assert_cmphex(res, ==, 0xbaadf00d); + /* Junk after decimal */ str = "0.NaN"; endptr = NULL; res = 0xbaadf00d; @@ -2836,6 +2975,35 @@ static void test_qemu_strtosz_trailing(void) g_assert_cmpint(err, ==, -EINVAL); g_assert_cmphex(res, ==, 0xbaadf00d); + /* No support for binary literals; 'b' is valid suffix */ + str = "0b1000"; + endptr = NULL; + res = 0xbaadf00d; + err = qemu_strtosz(str, &endptr, &res); + g_assert_cmpint(err, ==, 0); + g_assert_cmpuint(res, ==, 0); + g_assert(endptr == str + 2); + + res = 0xbaadf00d; + err = qemu_strtosz(str, NULL, &res); + g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmphex(res, ==, 0xbaadf00d); + + /* Hex literals use only one leading zero */ + str = "00x1"; + endptr = NULL; + res = 0xbaadf00d; + err = qemu_strtosz(str, &endptr, &res); + g_assert_cmpint(err, ==, 0); + g_assert_cmpuint(res, ==, 0); + g_assert(endptr == str + 2); + + res = 0xbaadf00d; + err = qemu_strtosz(str, NULL, &res); + g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmphex(res, ==, 0xbaadf00d); + + /* Although negatives are invalid, '-' may be in trailing junk */ str = "123-45"; endptr = NULL; res = 0xbaadf00d; @@ -2849,6 +3017,19 @@ static void test_qemu_strtosz_trailing(void) g_assert_cmpint(err, ==, -EINVAL); g_assert_cmphex(res, ==, 0xbaadf00d); + str = " 123 - 45"; + endptr = NULL; + res = 0xbaadf00d; + err = qemu_strtosz(str, &endptr, &res); + g_assert_cmpint(err, ==, 0); + g_assert_cmpuint(res, ==, 123); + g_assert(endptr == str + 4); + + res = 0xbaadf00d; + err = qemu_strtosz(str, NULL, &res); + g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmphex(res, ==, 0xbaadf00d); + /* FIXME should stop parse after 'e'. No floating point exponents */ str = "1.5e1k"; endptr = NULL; @@ -2861,7 +3042,7 @@ static void test_qemu_strtosz_trailing(void) res = 0xbaadf00d; err = qemu_strtosz(str, NULL, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmpint(res, ==, 0xbaadf00d); + g_assert_cmphex(res, ==, 0xbaadf00d); str = "1.5E+0k"; endptr = NULL; @@ -2875,6 +3056,20 @@ static void test_qemu_strtosz_trailing(void) err = qemu_strtosz(str, NULL, &res); g_assert_cmpint(err, ==, -EINVAL); g_assert_cmphex(res, ==, 0xbaadf00d); + + /* FIXME overflow in fraction is buggy */ + str = "1.5E999"; + endptr = NULL; + res = 0xbaadf00d; + err = qemu_strtosz(str, &endptr, &res); + g_assert_cmpint(err, ==, 0); + g_assert_cmpuint(res, ==, EiB /* FIXME EiB * 1.5 */); + g_assert(endptr == str + 9 /* FIXME + 4 */); + + res = 0xbaadf00d; + err = qemu_strtosz(str, NULL, &res); + g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmphex(res, ==, 0xbaadf00d); } static void test_qemu_strtosz_erange(void) @@ -2921,6 +3116,15 @@ static void test_qemu_strtosz_metric(void) g_assert_cmpint(err, ==, 0); g_assert_cmpuint(res, ==, 12345000); g_assert_true(endptr == str + 7); + + /* Fraction is affected by floating-point rounding */ + str = "18.446744073709550591E"; /* resembles 0xfffffffffffffbff */ + endptr = str; + res = 0xbaadf00d; + err = qemu_strtosz_metric(str, &endptr, &res); + g_assert_cmpint(err, ==, 0); + g_assert_cmpuint(res, ==, 0xfffffffffffffc0c); + g_assert_true(endptr == str + 22); } static void test_freq_to_str(void) From patchwork Mon May 8 20:03:39 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Blake X-Patchwork-Id: 13235007 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 23057C77B7F for ; Mon, 8 May 2023 20:06:22 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pw75h-0006Gs-Cm; Mon, 08 May 2023 16:04:13 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pw75O-0006EX-Sw for qemu-devel@nongnu.org; Mon, 08 May 2023 16:03:58 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pw75N-0007Jb-2t for qemu-devel@nongnu.org; Mon, 08 May 2023 16:03:54 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1683576231; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=whyBs5mAysxv+XUkFP6xBPNl40iBrpCDWkGw73gqdQM=; b=IsEsEMDzK16zmn1NXR2ut2yFoRi5NSKyXzqcbiH3GZ5rHMVlfuKtNVkVVRalnuuEhAmuHS YSzsJeWpGTuJ9pBVHiWd6S7dIsVFA8mgfcVr0VgLyVGJ1YgNoJeLr+KSctgxH9/MEsur8y jADyajiB7XT5gEp+iLiZqPOuaKSLDXI= Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-648-3cZGzyyFPEmBmCyftquVQQ-1; Mon, 08 May 2023 16:03:49 -0400 X-MC-Unique: 3cZGzyyFPEmBmCyftquVQQ-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 32FE11C0519E; Mon, 8 May 2023 20:03:49 +0000 (UTC) Received: from green.redhat.com (unknown [10.2.16.49]) by smtp.corp.redhat.com (Postfix) with ESMTP id 680161121314; Mon, 8 May 2023 20:03:48 +0000 (UTC) From: Eric Blake To: qemu-devel@nongnu.org Cc: hreitz@redhat.com, Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , Yanan Wang Subject: [PATCH 07/11] numa: Check for qemu_strtosz_MiB error Date: Mon, 8 May 2023 15:03:39 -0500 Message-Id: <20230508200343.791450-8-eblake@redhat.com> In-Reply-To: <20230508200343.791450-1-eblake@redhat.com> References: <20230508200343.791450-1-eblake@redhat.com> MIME-Version: 1.0 Content-type: text/plain X-Scanned-By: MIMEDefang 3.1 on 10.11.54.3 Received-SPF: pass client-ip=170.10.133.124; envelope-from=eblake@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org As shown in the previous commit, qemu_strtosz_MiB sometimes leaves the result value untoutched (we have to audit further to learn that in that case, the QAPI generator says that visit_type_NumaOptions() will have zero-initialized it), and sometimes leaves it with the value of a partial parse before -EINVAL occurs because of trailing garbage. Rather than blindly treating any string the user may throw at us as valid, we should check for parse failures. Fiuxes: cc001888 ("numa: fixup parsed NumaNodeOptions earlier", v2.11.0) Signed-off-by: Eric Blake --- hw/core/numa.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/hw/core/numa.c b/hw/core/numa.c index d8d36b16d80..f08956ddb0f 100644 --- a/hw/core/numa.c +++ b/hw/core/numa.c @@ -531,10 +531,17 @@ static int parse_numa(void *opaque, QemuOpts *opts, Error **errp) /* Fix up legacy suffix-less format */ if ((object->type == NUMA_OPTIONS_TYPE_NODE) && object->u.node.has_mem) { const char *mem_str = qemu_opt_get(opts, "mem"); - qemu_strtosz_MiB(mem_str, NULL, &object->u.node.mem); + int ret = qemu_strtosz_MiB(mem_str, NULL, &object->u.node.mem); + + if (ret < 0) { + error_setg_errno(&err, -ret, "could not parse memory size '%s'", + mem_str); + } } - set_numa_options(ms, object, &err); + if (!err) { + set_numa_options(ms, object, &err); + } qapi_free_NumaOptions(object); if (err) { From patchwork Mon May 8 20:03:40 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Blake X-Patchwork-Id: 13234999 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 1F95AC7EE2A for ; Mon, 8 May 2023 20:04:32 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pw75b-0006GB-6M; Mon, 08 May 2023 16:04:07 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pw75P-0006EZ-9K for qemu-devel@nongnu.org; Mon, 08 May 2023 16:03:58 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pw75M-0007Jn-TA for qemu-devel@nongnu.org; Mon, 08 May 2023 16:03:55 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1683576231; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=G22OnOyAe2863Q1QJFr/0hmyHHaHf3TwbESSTF+Hoq4=; b=Uy7wH65TFeYMECUU021mgFyeniHFS3sCRXpHfIijE/4gPEUrVlPYxinXH2rKvRkPlNZ7SC 7Q7o+F9w3cytFRTw4vdNt85kvHSOpw+4oX9WoeU/dz2EKjY3ig9lwAASSxWQ5m3JrQq6Sj WeRlAP+AuL5dVxWxa9c14fxTMfcbiYM= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-662-LjZlTJlCPByFaglPABAWvg-1; Mon, 08 May 2023 16:03:49 -0400 X-MC-Unique: LjZlTJlCPByFaglPABAWvg-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id A4826101A531 for ; Mon, 8 May 2023 20:03:49 +0000 (UTC) Received: from green.redhat.com (unknown [10.2.16.49]) by smtp.corp.redhat.com (Postfix) with ESMTP id 629521121314; Mon, 8 May 2023 20:03:49 +0000 (UTC) From: Eric Blake To: qemu-devel@nongnu.org Cc: hreitz@redhat.com Subject: [PATCH 08/11] cutils: Set value in all qemu_strtosz* error paths Date: Mon, 8 May 2023 15:03:40 -0500 Message-Id: <20230508200343.791450-9-eblake@redhat.com> In-Reply-To: <20230508200343.791450-1-eblake@redhat.com> References: <20230508200343.791450-1-eblake@redhat.com> MIME-Version: 1.0 Content-type: text/plain X-Scanned-By: MIMEDefang 3.1 on 10.11.54.3 Received-SPF: pass client-ip=170.10.133.124; envelope-from=eblake@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Making callers determine whether or not *value was populated on error is not nice for usability. Pre-patch, we have unit tests that check that *result is left unchanged on most EINVAL errors and set to 0 on many ERANGE errors. This is subtly different from libc strtoumax() behavior which returns UINT64_MAX on ERANGE errors, as well as different from our parse_uint() which slams to 0 on EINVAL on the grounds that we want our functions to be harder to mis-use than strtoumax(). Let's audit callers: - hw/core/numa.c:parse_numa() fixed in the previous patch to check for errors - migration/migration-hmp-cmds.c:hmp_migrate_set_parameter(), monitor/hmp.c:monitor_parse_arguments(), qapi/opts-visitor.c:opts_type_size(), qapi/qobject-input-visitor.c:qobject_input_type_size_keyval(), qemu-img.c:cvtnum_full(), qemu-io-cmds.c:cvtnum(), target/i386/cpu.c:x86_cpu_parse_featurestr(), and util/qemu-option.c:parse_option_size() appear to reject all failures (although some with distinct messages for ERANGE as opposed to EINVAL), so it doesn't matter what is in the value parameter on error. - All remaining callers are in the testsuite, where we can tweak our expectations to match our new desired behavior. Advancing to the end of the string parsed on overflow (ERANGE), while still returning 0, makes sense (UINT64_MAX as a size is unlikely to be useful); likewise, our size parsing code is complex enough that it's easier to always return 0 when endptr is NULL but trailing garbage was found, rather than trying to return the value of the prefix actually parsed (no current caller cared about the value of the prefix). Signed-off-by: Eric Blake --- tests/unit/test-cutils.c | 72 ++++++++++++++++++++-------------------- util/cutils.c | 17 +++++++--- 2 files changed, 48 insertions(+), 41 deletions(-) diff --git a/tests/unit/test-cutils.c b/tests/unit/test-cutils.c index 9fa6fb042e8..9cf00a810e4 100644 --- a/tests/unit/test-cutils.c +++ b/tests/unit/test-cutils.c @@ -2684,7 +2684,7 @@ static void test_qemu_strtosz_float(void) res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL /* FIXME 0 */); - g_assert_cmpuint(res, ==, 0xbaadf00d /* FIXME 512 */); + g_assert_cmpuint(res, ==, 0 /* FIXME 512 */); g_assert_true(endptr == str /* FIXME + 4 */); /* For convenience, we permit values that are not byte-exact */ @@ -2736,7 +2736,7 @@ static void test_qemu_strtosz_invalid(void) res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmphex(res, ==, 0xbaadf00d); + g_assert_cmpuint(res, ==, 0); g_assert_null(endptr); str = ""; @@ -2744,7 +2744,7 @@ static void test_qemu_strtosz_invalid(void) res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmphex(res, ==, 0xbaadf00d); + g_assert_cmpuint(res, ==, 0); g_assert_true(endptr == str); str = " \t "; @@ -2752,7 +2752,7 @@ static void test_qemu_strtosz_invalid(void) res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmphex(res, ==, 0xbaadf00d); + g_assert_cmpuint(res, ==, 0); g_assert_true(endptr == str); str = "."; @@ -2760,14 +2760,14 @@ static void test_qemu_strtosz_invalid(void) res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmphex(res, ==, 0xbaadf00d); + g_assert_cmpuint(res, ==, 0); g_assert(endptr == str); str = " ."; endptr = NULL; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmphex(res, ==, 0xbaadf00d); + g_assert_cmpuint(res, ==, 0); g_assert(endptr == str); str = "crap"; @@ -2775,7 +2775,7 @@ static void test_qemu_strtosz_invalid(void) res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmphex(res, ==, 0xbaadf00d); + g_assert_cmpuint(res, ==, 0); g_assert_true(endptr == str); str = "inf"; @@ -2783,7 +2783,7 @@ static void test_qemu_strtosz_invalid(void) res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmphex(res, ==, 0xbaadf00d); + g_assert_cmpuint(res, ==, 0); g_assert_true(endptr == str); str = "NaN"; @@ -2791,7 +2791,7 @@ static void test_qemu_strtosz_invalid(void) res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmphex(res, ==, 0xbaadf00d); + g_assert_cmpuint(res, ==, 0); g_assert_true(endptr == str); /* Fractional values require scale larger than bytes */ @@ -2800,7 +2800,7 @@ static void test_qemu_strtosz_invalid(void) res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmphex(res, ==, 0xbaadf00d); + g_assert_cmpuint(res, ==, 0); g_assert_true(endptr == str); str = "1.1"; @@ -2808,7 +2808,7 @@ static void test_qemu_strtosz_invalid(void) res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmphex(res, ==, 0xbaadf00d); + g_assert_cmpuint(res, ==, 0); g_assert_true(endptr == str); /* FIXME Fraction tail can cause ERANGE overflow */ @@ -2817,7 +2817,7 @@ static void test_qemu_strtosz_invalid(void) res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, 0 /* FIXME -ERANGE */); - g_assert_cmpuint(res, ==, 15ULL * EiB /* FIXME 0xbaadf00d */); + g_assert_cmpuint(res, ==, 15ULL * EiB /* FIXME 0 */); g_assert_true(endptr == str + 56 /* FIXME str */); /* FIXME ERANGE underflow in the fraction tail should matter for 'B' */ @@ -2834,7 +2834,7 @@ static void test_qemu_strtosz_invalid(void) res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, 0 /* FIXME -EINVAL */); - g_assert_cmpuint(res, ==, 1 /* FIXME 0xbaadf00d */); + g_assert_cmpuint(res, ==, 1 /* FIXME 0 */); g_assert_true(endptr == str + 354 /* FIXME str */); /* No hex fractions */ @@ -2843,7 +2843,7 @@ static void test_qemu_strtosz_invalid(void) res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmphex(res, ==, 0xbaadf00d); + g_assert_cmpuint(res, ==, 0); g_assert_true(endptr == str); /* No suffixes */ @@ -2852,7 +2852,7 @@ static void test_qemu_strtosz_invalid(void) res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmphex(res, ==, 0xbaadf00d); + g_assert_cmpuint(res, ==, 0); g_assert_true(endptr == str); str = "0x1p1"; @@ -2860,7 +2860,7 @@ static void test_qemu_strtosz_invalid(void) res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmphex(res, ==, 0xbaadf00d); + g_assert_cmpuint(res, ==, 0); g_assert(endptr == str); /* No negative values */ @@ -2869,7 +2869,7 @@ static void test_qemu_strtosz_invalid(void) res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmphex(res, ==, 0xbaadf00d); + g_assert_cmpuint(res, ==, 0); g_assert_true(endptr == str); str = "-1"; @@ -2877,7 +2877,7 @@ static void test_qemu_strtosz_invalid(void) res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmphex(res, ==, 0xbaadf00d); + g_assert_cmpuint(res, ==, 0); g_assert_true(endptr == str); str = "-.0k"; @@ -2885,7 +2885,7 @@ static void test_qemu_strtosz_invalid(void) res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmphex(res, ==, 0xbaadf00d); + g_assert_cmpuint(res, ==, 0); g_assert_true(endptr == str); /* Too many decimals */ @@ -2894,7 +2894,7 @@ static void test_qemu_strtosz_invalid(void) res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmphex(res, ==, 0xbaadf00d); + g_assert_cmpuint(res, ==, 0); g_assert(endptr == str); } @@ -2917,7 +2917,7 @@ static void test_qemu_strtosz_trailing(void) res = 0xbaadf00d; err = qemu_strtosz(str, NULL, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmphex(res, ==, 0xbaadf00d); + g_assert_cmpuint(res, ==, 0); /* Unknown suffix */ str = "123xxx"; @@ -2931,7 +2931,7 @@ static void test_qemu_strtosz_trailing(void) res = 0xbaadf00d; err = qemu_strtosz(str, NULL, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmphex(res, ==, 0xbaadf00d); + g_assert_cmpuint(res, ==, 0); /* Junk after one-byte suffix */ str = "1kiB"; @@ -2945,7 +2945,7 @@ static void test_qemu_strtosz_trailing(void) res = 0xbaadf00d; err = qemu_strtosz(str, NULL, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmphex(res, ==, 0xbaadf00d); + g_assert_cmpuint(res, ==, 0); /* Incomplete hex is an unknown suffix */ str = "0x"; @@ -2959,7 +2959,7 @@ static void test_qemu_strtosz_trailing(void) res = 0xbaadf00d; err = qemu_strtosz(str, NULL, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmphex(res, ==, 0xbaadf00d); + g_assert_cmpuint(res, ==, 0); /* Junk after decimal */ str = "0.NaN"; @@ -2973,7 +2973,7 @@ static void test_qemu_strtosz_trailing(void) res = 0xbaadf00d; err = qemu_strtosz(str, NULL, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmphex(res, ==, 0xbaadf00d); + g_assert_cmpuint(res, ==, 0); /* No support for binary literals; 'b' is valid suffix */ str = "0b1000"; @@ -2987,7 +2987,7 @@ static void test_qemu_strtosz_trailing(void) res = 0xbaadf00d; err = qemu_strtosz(str, NULL, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmphex(res, ==, 0xbaadf00d); + g_assert_cmpuint(res, ==, 0); /* Hex literals use only one leading zero */ str = "00x1"; @@ -3001,7 +3001,7 @@ static void test_qemu_strtosz_trailing(void) res = 0xbaadf00d; err = qemu_strtosz(str, NULL, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmphex(res, ==, 0xbaadf00d); + g_assert_cmpuint(res, ==, 0); /* Although negatives are invalid, '-' may be in trailing junk */ str = "123-45"; @@ -3015,7 +3015,7 @@ static void test_qemu_strtosz_trailing(void) res = 0xbaadf00d; err = qemu_strtosz(str, NULL, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmphex(res, ==, 0xbaadf00d); + g_assert_cmpuint(res, ==, 0); str = " 123 - 45"; endptr = NULL; @@ -3028,7 +3028,7 @@ static void test_qemu_strtosz_trailing(void) res = 0xbaadf00d; err = qemu_strtosz(str, NULL, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmphex(res, ==, 0xbaadf00d); + g_assert_cmpuint(res, ==, 0); /* FIXME should stop parse after 'e'. No floating point exponents */ str = "1.5e1k"; @@ -3036,26 +3036,26 @@ static void test_qemu_strtosz_trailing(void) res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL /* FIXME 0 */); - g_assert_cmphex(res, ==, 0xbaadf00d /* FIXME EiB * 1.5 */); + g_assert_cmpuint(res, ==, 0 /* FIXME EiB * 1.5 */); g_assert_true(endptr == str /* FIXME + 4 */); res = 0xbaadf00d; err = qemu_strtosz(str, NULL, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmphex(res, ==, 0xbaadf00d); + g_assert_cmpuint(res, ==, 0); str = "1.5E+0k"; endptr = NULL; res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL /* FIXME 0 */); - g_assert_cmphex(res, ==, 0xbaadf00d /* FIXME EiB * 1.5 */); + g_assert_cmpuint(res, ==, 0 /* FIXME EiB * 1.5 */); g_assert_true(endptr == str /* FIXME + 4 */); res = 0xbaadf00d; err = qemu_strtosz(str, NULL, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmphex(res, ==, 0xbaadf00d); + g_assert_cmpuint(res, ==, 0); /* FIXME overflow in fraction is buggy */ str = "1.5E999"; @@ -3069,7 +3069,7 @@ static void test_qemu_strtosz_trailing(void) res = 0xbaadf00d; err = qemu_strtosz(str, NULL, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmphex(res, ==, 0xbaadf00d); + g_assert_cmpuint(res, ==, 0); } static void test_qemu_strtosz_erange(void) @@ -3083,14 +3083,14 @@ static void test_qemu_strtosz_erange(void) endptr = NULL; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -ERANGE); - g_assert_cmphex(res, ==, 0xbaadf00d); + g_assert_cmpuint(res, ==, 0); g_assert_true(endptr == str + 20); str = "20E"; endptr = NULL; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -ERANGE); - g_assert_cmphex(res, ==, 0xbaadf00d); + g_assert_cmpuint(res, ==, 0); g_assert_true(endptr == str + 3); } diff --git a/util/cutils.c b/util/cutils.c index 5887e744140..8bacf349383 100644 --- a/util/cutils.c +++ b/util/cutils.c @@ -205,13 +205,15 @@ static int64_t suffix_mul(char suffix, int64_t unit) * * The end pointer will be returned in *end, if not NULL. If there is * no fraction, the input can be decimal or hexadecimal; if there is a - * fraction, then the input must be decimal and there must be a suffix - * (possibly by @default_suffix) larger than Byte, and the fractional - * portion may suffer from precision loss or rounding. The input must - * be positive. + * non-zero fraction, then the input must be decimal and there must be + * a suffix (possibly by @default_suffix) larger than Byte, and the + * fractional portion may suffer from precision loss or rounding. The + * input must be positive. * * Return -ERANGE on overflow (with *@end advanced), and -EINVAL on - * other error (with *@end left unchanged). + * other error (with *@end at @nptr). Unlike strtoull, *@result is + * set to 0 on all errors, as returning UINT64_MAX on overflow is less + * likely to be usable as a size. */ static int do_strtosz(const char *nptr, const char **end, const char default_suffix, int64_t unit, @@ -311,6 +313,11 @@ out: } if (retval == 0) { *result = val; + } else { + *result = 0; + if (end && retval == -EINVAL) { + *end = nptr; + } } return retval; From patchwork Mon May 8 20:03:41 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Blake X-Patchwork-Id: 13235006 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 8D457C7EE22 for ; Mon, 8 May 2023 20:06:10 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pw75h-0006Gq-CS; Mon, 08 May 2023 16:04:13 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pw75O-0006EY-TI for qemu-devel@nongnu.org; Mon, 08 May 2023 16:03:58 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pw75M-0007Jp-Rs for qemu-devel@nongnu.org; Mon, 08 May 2023 16:03:54 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1683576231; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=5LJfuVrf9CfB89/AOAQief0WsZJTAoI/ADeZuAtvlmM=; b=cUF9vut7CzaorBZpl+eCfM/tmi75dc1Cw1V8Rd14LHKPuSbJeduBP5nZ+vHF5WkwBYLQ// bRogUIxpGs1A+eySK3s9YCU9tEcTU+XMSrb2K66c62ZxyWw708+n0jwbO1dx2Nc4F/0vyA H72ViFVf0ZBKhKv9r8Q7QLoGjHSktsA= Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-612-7gF5eys6OaWxbd3h8xu3fQ-1; Mon, 08 May 2023 16:03:50 -0400 X-MC-Unique: 7gF5eys6OaWxbd3h8xu3fQ-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 27F673C0ED41 for ; Mon, 8 May 2023 20:03:50 +0000 (UTC) Received: from green.redhat.com (unknown [10.2.16.49]) by smtp.corp.redhat.com (Postfix) with ESMTP id D8F8D1121314; Mon, 8 May 2023 20:03:49 +0000 (UTC) From: Eric Blake To: qemu-devel@nongnu.org Cc: hreitz@redhat.com Subject: [PATCH 09/11] cutils: Set value in all integral qemu_strto* error paths Date: Mon, 8 May 2023 15:03:41 -0500 Message-Id: <20230508200343.791450-10-eblake@redhat.com> In-Reply-To: <20230508200343.791450-1-eblake@redhat.com> References: <20230508200343.791450-1-eblake@redhat.com> MIME-Version: 1.0 Content-type: text/plain X-Scanned-By: MIMEDefang 3.1 on 10.11.54.3 Received-SPF: pass client-ip=170.10.133.124; envelope-from=eblake@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Our goal in writing qemu_strtoi() and friends is to have an interface harder to abuse than libc's strtol(). Leaving the return value initialized on some error paths does not lend itself well to this goal; and our documentation wasn't helpful on the matter. Note that the previous patch changed all qemu_strtosz() EINVAL error paths to slam value to 0 rather than stay uninitialized, even when the EINVAL eror occurs because of trailing junk. But for the remaining integral qemu_strto*, it's easier to return the parsed value than to force things back to zero, in part because of how check_strtox_error works; and doing so creates less churn in the testsuite. Here, the list of affected callers is much longer ('git grep "qemu_strto[ui]" *.c **/*.c | grep -v tests/ |wc -l' outputs 87, although a few of those are the implementation in in cutils.c), so touching as little as possible is the wisest course of action. Signed-off-by: Eric Blake --- tests/unit/test-cutils.c | 24 +++++++++++------------ util/cutils.c | 42 +++++++++++++++++++++++++--------------- 2 files changed, 38 insertions(+), 28 deletions(-) diff --git a/tests/unit/test-cutils.c b/tests/unit/test-cutils.c index 9cf00a810e4..2cb33e41ae4 100644 --- a/tests/unit/test-cutils.c +++ b/tests/unit/test-cutils.c @@ -250,7 +250,7 @@ static void test_qemu_strtoi_null(void) err = qemu_strtoi(NULL, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmpint(res, ==, 999); + g_assert_cmpint(res, ==, 0); g_assert_null(endptr); } @@ -479,7 +479,7 @@ static void test_qemu_strtoi_full_null(void) err = qemu_strtoi(NULL, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmpint(res, ==, 999); + g_assert_cmpint(res, ==, 0); g_assert_null(endptr); } @@ -557,7 +557,7 @@ static void test_qemu_strtoui_null(void) err = qemu_strtoui(NULL, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmpuint(res, ==, 999); + g_assert_cmpuint(res, ==, 0); g_assert_null(endptr); } @@ -784,7 +784,7 @@ static void test_qemu_strtoui_full_null(void) err = qemu_strtoui(NULL, NULL, 0, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmpuint(res, ==, 999); + g_assert_cmpuint(res, ==, 0); } static void test_qemu_strtoui_full_empty(void) @@ -860,7 +860,7 @@ static void test_qemu_strtol_null(void) err = qemu_strtol(NULL, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmpint(res, ==, 999); + g_assert_cmpint(res, ==, 0); g_assert_null(endptr); } @@ -1087,7 +1087,7 @@ static void test_qemu_strtol_full_null(void) err = qemu_strtol(NULL, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmpint(res, ==, 999); + g_assert_cmpint(res, ==, 0); g_assert_null(endptr); } @@ -1165,7 +1165,7 @@ static void test_qemu_strtoul_null(void) err = qemu_strtoul(NULL, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmpuint(res, ==, 999); + g_assert_cmpuint(res, ==, 0); g_assert_null(endptr); } @@ -1390,7 +1390,7 @@ static void test_qemu_strtoul_full_null(void) err = qemu_strtoul(NULL, NULL, 0, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmpuint(res, ==, 999); + g_assert_cmpuint(res, ==, 0); } static void test_qemu_strtoul_full_empty(void) @@ -1466,7 +1466,7 @@ static void test_qemu_strtoi64_null(void) err = qemu_strtoi64(NULL, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmpint(res, ==, 999); + g_assert_cmpint(res, ==, 0); g_assert_null(endptr); } @@ -1691,7 +1691,7 @@ static void test_qemu_strtoi64_full_null(void) err = qemu_strtoi64(NULL, NULL, 0, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmpint(res, ==, 999); + g_assert_cmpint(res, ==, 0); } static void test_qemu_strtoi64_full_empty(void) @@ -1769,7 +1769,7 @@ static void test_qemu_strtou64_null(void) err = qemu_strtou64(NULL, &endptr, 0, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmpuint(res, ==, 999); + g_assert_cmpuint(res, ==, 0); g_assert_null(endptr); } @@ -1994,7 +1994,7 @@ static void test_qemu_strtou64_full_null(void) err = qemu_strtou64(NULL, NULL, 0, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmpuint(res, ==, 999); + g_assert_cmpuint(res, ==, 0); } static void test_qemu_strtou64_full_empty(void) diff --git a/util/cutils.c b/util/cutils.c index 8bacf349383..83948926ec9 100644 --- a/util/cutils.c +++ b/util/cutils.c @@ -384,12 +384,13 @@ static int check_strtox_error(const char *nptr, char *ep, * * @nptr may be null, and no conversion is performed then. * - * If no conversion is performed, store @nptr in *@endptr and return - * -EINVAL. + * If no conversion is performed, store @nptr in *@endptr, 0 in + * @result, and return -EINVAL. * * If @endptr is null, and the string isn't fully converted, return - * -EINVAL. This is the case when the pointer that would be stored in - * a non-null @endptr points to a character other than '\0'. + * -EINVAL with @result set to the parsed value. This is the case + * when the pointer that would be stored in a non-null @endptr points + * to a character other than '\0'. * * If the conversion overflows @result, store INT_MAX in @result, * and return -ERANGE. @@ -407,6 +408,7 @@ int qemu_strtoi(const char *nptr, const char **endptr, int base, assert((unsigned) base <= 36 && base != 1); if (!nptr) { + *result = 0; if (endptr) { *endptr = nptr; } @@ -436,12 +438,13 @@ int qemu_strtoi(const char *nptr, const char **endptr, int base, * * @nptr may be null, and no conversion is performed then. * - * If no conversion is performed, store @nptr in *@endptr and return - * -EINVAL. + * If no conversion is performed, store @nptr in *@endptr, 0 in + * @result, and return -EINVAL. * * If @endptr is null, and the string isn't fully converted, return - * -EINVAL. This is the case when the pointer that would be stored in - * a non-null @endptr points to a character other than '\0'. + * -EINVAL with @result set to the parsed value. This is the case + * when the pointer that would be stored in a non-null @endptr points + * to a character other than '\0'. * * If the conversion overflows @result, store UINT_MAX in @result, * and return -ERANGE. @@ -460,6 +463,7 @@ int qemu_strtoui(const char *nptr, const char **endptr, int base, assert((unsigned) base <= 36 && base != 1); if (!nptr) { + *result = 0; if (endptr) { *endptr = nptr; } @@ -495,12 +499,13 @@ int qemu_strtoui(const char *nptr, const char **endptr, int base, * * @nptr may be null, and no conversion is performed then. * - * If no conversion is performed, store @nptr in *@endptr and return - * -EINVAL. + * If no conversion is performed, store @nptr in *@endptr, 0 in + * @result, and return -EINVAL. * * If @endptr is null, and the string isn't fully converted, return - * -EINVAL. This is the case when the pointer that would be stored in - * a non-null @endptr points to a character other than '\0'. + * -EINVAL with @result set to the parsed value. This is the case + * when the pointer that would be stored in a non-null @endptr points + * to a character other than '\0'. * * If the conversion overflows @result, store LONG_MAX in @result, * and return -ERANGE. @@ -517,6 +522,7 @@ int qemu_strtol(const char *nptr, const char **endptr, int base, assert((unsigned) base <= 36 && base != 1); if (!nptr) { + *result = 0; if (endptr) { *endptr = nptr; } @@ -537,12 +543,13 @@ int qemu_strtol(const char *nptr, const char **endptr, int base, * * @nptr may be null, and no conversion is performed then. * - * If no conversion is performed, store @nptr in *@endptr and return - * -EINVAL. + * If no conversion is performed, store @nptr in *@endptr, 0 in + * @result, and return -EINVAL. * * If @endptr is null, and the string isn't fully converted, return - * -EINVAL. This is the case when the pointer that would be stored in - * a non-null @endptr points to a character other than '\0'. + * -EINVAL with @result set to the parsed value. This is the case + * when the pointer that would be stored in a non-null @endptr points + * to a character other than '\0'. * * If the conversion overflows @result, store ULONG_MAX in @result, * and return -ERANGE. @@ -560,6 +567,7 @@ int qemu_strtoul(const char *nptr, const char **endptr, int base, assert((unsigned) base <= 36 && base != 1); if (!nptr) { + *result = 0; if (endptr) { *endptr = nptr; } @@ -588,6 +596,7 @@ int qemu_strtoi64(const char *nptr, const char **endptr, int base, assert((unsigned) base <= 36 && base != 1); if (!nptr) { + *result = 0; if (endptr) { *endptr = nptr; } @@ -613,6 +622,7 @@ int qemu_strtou64(const char *nptr, const char **endptr, int base, assert((unsigned) base <= 36 && base != 1); if (!nptr) { + *result = 0; if (endptr) { *endptr = nptr; } From patchwork Mon May 8 20:03:42 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Blake X-Patchwork-Id: 13235002 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 58EB2C77B7F for ; Mon, 8 May 2023 20:05:22 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pw75r-0006Jx-0m; Mon, 08 May 2023 16:04:23 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pw75T-0006Eh-6F for qemu-devel@nongnu.org; Mon, 08 May 2023 16:04:00 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pw75N-0007Jy-86 for qemu-devel@nongnu.org; Mon, 08 May 2023 16:03:56 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1683576232; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=eSy16GFae7cjXsOqJEmnMXO1oOnGhcIHo44fbM7C1Ho=; b=bghHp4tc1QqAKY/axjsTZTg/Jt3IVYakIY7Gx6YA2JpCGNYneHvskIKtPn7pAxn7p7pGz9 ycEyP3Z4GBdGz42UsUsH73Cfu33ql+4V7TgpC7nXUVeYPWoeVg3J5IeVHnOL2MLVLzzKYu DjW5MQUAU8T4nyqGjX5Sv0sXBwtKGO8= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-160-BJ4XviapMp-ImP_ectTl3A-1; Mon, 08 May 2023 16:03:50 -0400 X-MC-Unique: BJ4XviapMp-ImP_ectTl3A-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 98F571011579 for ; Mon, 8 May 2023 20:03:50 +0000 (UTC) Received: from green.redhat.com (unknown [10.2.16.49]) by smtp.corp.redhat.com (Postfix) with ESMTP id 565021121314; Mon, 8 May 2023 20:03:50 +0000 (UTC) From: Eric Blake To: qemu-devel@nongnu.org Cc: hreitz@redhat.com Subject: [PATCH 10/11] cutils: Improve qemu_strtod* error paths Date: Mon, 8 May 2023 15:03:42 -0500 Message-Id: <20230508200343.791450-11-eblake@redhat.com> In-Reply-To: <20230508200343.791450-1-eblake@redhat.com> References: <20230508200343.791450-1-eblake@redhat.com> MIME-Version: 1.0 Content-type: text/plain X-Scanned-By: MIMEDefang 3.1 on 10.11.54.3 Received-SPF: pass client-ip=170.10.133.124; envelope-from=eblake@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Previous patches changed all integral qemu_strto*() error paths to guarantee that *value is never left uninitialized. Do likewise for qemu_strtod. Also, tighten qemu_strtod_finite() to never return a non-finite value (prior to this patch, we were rejecting "inf" with -EINVAL and unspecified result 0.0, but failing "9e999" with -ERANGE and HUGE_VAL - which is infinite on IEEE machines - despite our function claiming to recognize only finite values). Auditing callers, we have no external callers of qemu_strtod, and among the callers of qemu_strtod_finite: - qapi/qobject-input-visitor.c:qobject_input_type_number_keyval() and qapi/string-input-visitor.c:parse_type_number() which reject all errors (does not matter what we store) - utils/cutils.c:do_strtosz() incorrectly assumes that *endptr points to '.' on all failures (that is, it is not distinguishing between EINVAL and ERANGE; and therefore still does the WRONG THING for "9.9e999". The change here does not fix that (a later patch will tackle this more systematically), but at least the value of endptr is less likely to be out of bounds on overflow - our testsuite, which we can update to match what we document Signed-off-by: Eric Blake --- tests/unit/test-cutils.c | 57 +++++++++++++++++++++++++--------------- util/cutils.c | 32 +++++++++++++--------- 2 files changed, 55 insertions(+), 34 deletions(-) diff --git a/tests/unit/test-cutils.c b/tests/unit/test-cutils.c index 2cb33e41ae4..f781997aef7 100644 --- a/tests/unit/test-cutils.c +++ b/tests/unit/test-cutils.c @@ -2105,6 +2105,7 @@ static void test_qemu_strtod_einval(void) err = qemu_strtod(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); g_assert_cmpfloat(res, ==, 0.0); + g_assert_false(signbit(res)); g_assert_true(endptr == str); /* NULL */ @@ -2113,7 +2114,8 @@ static void test_qemu_strtod_einval(void) res = 999; err = qemu_strtod(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmpfloat(res, ==, 999.0); + g_assert_cmpfloat(res, ==, 0.0); + g_assert_false(signbit(res)); g_assert_null(endptr); /* not recognizable */ @@ -2123,6 +2125,7 @@ static void test_qemu_strtod_einval(void) err = qemu_strtod(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); g_assert_cmpfloat(res, ==, 0.0); + g_assert_false(signbit(res)); g_assert_true(endptr == str); } @@ -2309,7 +2312,8 @@ static void test_qemu_strtod_finite_einval(void) res = 999; err = qemu_strtod_finite(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmpfloat(res, ==, 999.0); + g_assert_cmpfloat(res, ==, 0.0); + g_assert_false(signbit(res)); g_assert_true(endptr == str); /* NULL */ @@ -2318,7 +2322,8 @@ static void test_qemu_strtod_finite_einval(void) res = 999; err = qemu_strtod_finite(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmpfloat(res, ==, 999.0); + g_assert_cmpfloat(res, ==, 0.0); + g_assert_false(signbit(res)); g_assert_null(endptr); /* not recognizable */ @@ -2327,7 +2332,8 @@ static void test_qemu_strtod_finite_einval(void) res = 999; err = qemu_strtod_finite(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmpfloat(res, ==, 999.0); + g_assert_cmpfloat(res, ==, 0.0); + g_assert_false(signbit(res)); g_assert_true(endptr == str); } @@ -2338,24 +2344,26 @@ static void test_qemu_strtod_finite_erange(void) int err; double res; - /* overflow */ + /* overflow turns into EINVAL */ str = "9e999"; endptr = NULL; res = 999; err = qemu_strtod_finite(str, &endptr, &res); - g_assert_cmpint(err, ==, -ERANGE); - g_assert_cmpfloat(res, ==, HUGE_VAL); - g_assert_true(endptr == str + 5); + g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpfloat(res, ==, 0.0); + g_assert_false(signbit(res)); + g_assert_true(endptr == str); str = "-9e+999"; endptr = NULL; res = 999; err = qemu_strtod_finite(str, &endptr, &res); - g_assert_cmpint(err, ==, -ERANGE); - g_assert_cmpfloat(res, ==, -HUGE_VAL); - g_assert_true(endptr == str + 7); + g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpfloat(res, ==, 0.0); + g_assert_false(signbit(res)); + g_assert_true(endptr == str); - /* underflow */ + /* underflow is still possible */ str = "-9e-999"; endptr = NULL; res = 999; @@ -2380,7 +2388,8 @@ static void test_qemu_strtod_finite_nonfinite(void) res = 999; err = qemu_strtod_finite(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmpfloat(res, ==, 999.0); + g_assert_cmpfloat(res, ==, 0.0); + g_assert_false(signbit(res)); g_assert_true(endptr == str); str = "-infinity"; @@ -2388,7 +2397,8 @@ static void test_qemu_strtod_finite_nonfinite(void) res = 999; err = qemu_strtod_finite(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmpfloat(res, ==, 999.0); + g_assert_cmpfloat(res, ==, 0.0); + g_assert_false(signbit(res)); g_assert_true(endptr == str); /* not a number */ @@ -2397,7 +2407,8 @@ static void test_qemu_strtod_finite_nonfinite(void) res = 999; err = qemu_strtod_finite(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmpfloat(res, ==, 999.0); + g_assert_cmpfloat(res, ==, 0.0); + g_assert_false(signbit(res)); g_assert_true(endptr == str); } @@ -2421,7 +2432,8 @@ static void test_qemu_strtod_finite_trailing(void) res = 999; err = qemu_strtod_finite(str, NULL, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmpfloat(res, ==, 999.0); + g_assert_cmpfloat(res, ==, 1.0); + g_assert_false(signbit(res)); /* trailing e is not an exponent */ str = ".5e"; @@ -2436,7 +2448,8 @@ static void test_qemu_strtod_finite_trailing(void) res = 999; err = qemu_strtod_finite(str, NULL, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmpfloat(res, ==, 999.0); + g_assert_cmpfloat(res, ==, 0.5); + g_assert_false(signbit(res)); /* trailing ( not part of long NaN */ str = "nan("; @@ -2444,14 +2457,16 @@ static void test_qemu_strtod_finite_trailing(void) res = 999; err = qemu_strtod_finite(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmpfloat(res, ==, 999.0); + g_assert_cmpfloat(res, ==, 0.0); + g_assert_false(signbit(res)); g_assert_true(endptr == str); endptr = NULL; res = 999; err = qemu_strtod_finite(str, NULL, &res); g_assert_cmpint(err, ==, -EINVAL); - g_assert_cmpfloat(res, ==, 999.0); + g_assert_cmpfloat(res, ==, 0.0); + g_assert_false(signbit(res)); } static void test_qemu_strtosz_simple(void) @@ -3063,8 +3078,8 @@ static void test_qemu_strtosz_trailing(void) res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, 0); - g_assert_cmpuint(res, ==, EiB /* FIXME EiB * 1.5 */); - g_assert(endptr == str + 9 /* FIXME + 4 */); + g_assert_cmpuint(res, ==, 1 /* FIXME EiB * 1.5 */); + g_assert(endptr == str + 2 /* FIXME + 4 */); res = 0xbaadf00d; err = qemu_strtosz(str, NULL, &res); diff --git a/util/cutils.c b/util/cutils.c index 83948926ec9..0e056a27a44 100644 --- a/util/cutils.c +++ b/util/cutils.c @@ -649,12 +649,13 @@ int qemu_strtou64(const char *nptr, const char **endptr, int base, * * @nptr may be null, and no conversion is performed then. * - * If no conversion is performed, store @nptr in *@endptr and return - * -EINVAL. + * If no conversion is performed, store @nptr in *@endptr, +0.0 in + * @result, and return -EINVAL. * * If @endptr is null, and the string isn't fully converted, return - * -EINVAL. This is the case when the pointer that would be stored in - * a non-null @endptr points to a character other than '\0'. + * -EINVAL with @result set to the parsed value. This is the case + * when the pointer that would be stored in a non-null @endptr points + * to a character other than '\0'. * * If the conversion overflows, store +/-HUGE_VAL in @result, depending * on the sign, and return -ERANGE. @@ -669,6 +670,7 @@ int qemu_strtod(const char *nptr, const char **endptr, double *result) char *ep; if (!nptr) { + *result = 0.0; if (endptr) { *endptr = nptr; } @@ -683,24 +685,28 @@ int qemu_strtod(const char *nptr, const char **endptr, double *result) /** * Convert string @nptr to a finite double. * - * Works like qemu_strtod(), except that "NaN" and "inf" are rejected - * with -EINVAL and no conversion is performed. + * Works like qemu_strtod(), except that "NaN", "inf", and strings + * that cause ERANGE overflow errors are rejected with -EINVAL as if + * no conversion is performed, storing 0.0 into @result regardless of + * any sign. -ERANGE failures for underflow still preserve the parsed + * sign. */ int qemu_strtod_finite(const char *nptr, const char **endptr, double *result) { - double tmp; + const char *tmp; int ret; - ret = qemu_strtod(nptr, endptr, &tmp); - if (!ret && !isfinite(tmp)) { + ret = qemu_strtod(nptr, &tmp, result); + if (!isfinite(*result)) { if (endptr) { *endptr = nptr; } + *result = 0.0; + ret = -EINVAL; + } else if (endptr) { + *endptr = tmp; + } else if (*tmp) { ret = -EINVAL; - } - - if (ret != -EINVAL) { - *result = tmp; } return ret; } From patchwork Mon May 8 20:03:43 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Blake X-Patchwork-Id: 13235001 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id DBCC8C77B7F for ; Mon, 8 May 2023 20:05:14 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pw75f-0006GD-9E; Mon, 08 May 2023 16:04:11 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pw75T-0006Ej-7V for qemu-devel@nongnu.org; Mon, 08 May 2023 16:04:00 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pw75N-0007KM-VV for qemu-devel@nongnu.org; Mon, 08 May 2023 16:03:56 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1683576233; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=MjsYTp4uMPaj6tl4VHV5SOUdxqW2VFNDpjp7ErZwpD0=; b=ilI6HyqUjO9eMapCqSq8S3l8oJux/KWOT34YU1S7VZvTkFGNOBw+vNNnGXx/c4hPPuy+m2 R0DzgIIgsg/3cRFJT/N255XQIHWslkL3qWLCBucICHtmJOOKMMpH3QOEY4azDLPO7u+I5C QpBPDCDHLXqWWr0xRCr5iaAhmwSwk0Y= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-629-FrONzesJNoOMq9I_AOzS4g-1; Mon, 08 May 2023 16:03:51 -0400 X-MC-Unique: FrONzesJNoOMq9I_AOzS4g-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 16DDA185A7A2 for ; Mon, 8 May 2023 20:03:51 +0000 (UTC) Received: from green.redhat.com (unknown [10.2.16.49]) by smtp.corp.redhat.com (Postfix) with ESMTP id C8F5F1121314; Mon, 8 May 2023 20:03:50 +0000 (UTC) From: Eric Blake To: qemu-devel@nongnu.org Cc: hreitz@redhat.com Subject: [PATCH 11/11] cutils: Improve qemu_strtosz handling of fractions Date: Mon, 8 May 2023 15:03:43 -0500 Message-Id: <20230508200343.791450-12-eblake@redhat.com> In-Reply-To: <20230508200343.791450-1-eblake@redhat.com> References: <20230508200343.791450-1-eblake@redhat.com> MIME-Version: 1.0 Content-type: text/plain X-Scanned-By: MIMEDefang 3.1 on 10.11.54.3 Received-SPF: pass client-ip=170.10.129.124; envelope-from=eblake@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org 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 Signed-off-by: Eric Blake --- tests/unit/test-cutils.c | 51 +++++++++++------------ util/cutils.c | 89 ++++++++++++++++++++++++++++------------ 2 files changed, 88 insertions(+), 52 deletions(-) diff --git a/tests/unit/test-cutils.c b/tests/unit/test-cutils.c index f781997aef7..1fb9d5323ab 100644 --- a/tests/unit/test-cutils.c +++ b/tests/unit/test-cutils.c @@ -2693,14 +2693,14 @@ static void test_qemu_strtosz_float(void) g_assert_cmpuint(res, ==, 1024); g_assert_true(endptr == str + 4); - /* FIXME An empty fraction head should be tolerated */ + /* An empty fraction head is tolerated */ str = " .5k"; endptr = str; res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); - g_assert_cmpint(err, ==, -EINVAL /* FIXME 0 */); - g_assert_cmpuint(res, ==, 0 /* FIXME 512 */); - g_assert_true(endptr == str /* FIXME + 4 */); + g_assert_cmpint(err, ==, 0); + g_assert_cmpuint(res, ==, 512); + g_assert_true(endptr == str + 4); /* For convenience, we permit values that are not byte-exact */ str = "12.345M"; @@ -2711,16 +2711,16 @@ static void test_qemu_strtosz_float(void) g_assert_cmpuint(res, ==, (uint64_t) (12.345 * MiB + 0.5)); g_assert_true(endptr == str + 7); - /* FIXME Fraction tail should round correctly */ + /* Fraction tail can round up */ str = "1.9999999999999999999999999999999999999999999999999999k"; endptr = str; res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, 0); - g_assert_cmpint(res, ==, 1024 /* FIXME 2048 */); + g_assert_cmpuint(res, ==, 2048); g_assert_true(endptr == str + 55); - /* FIXME ERANGE underflow in the fraction tail should not matter for 'k' */ + /* ERANGE underflow in the fraction tail does not matter for 'k' */ str = "1." "00000000000000000000000000000000000000000000000000" "00000000000000000000000000000000000000000000000000" @@ -2734,7 +2734,7 @@ static void test_qemu_strtosz_float(void) res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, 0); - g_assert_cmpuint(res, ==, 1 /* FIXME 1024 */); + g_assert_cmpuint(res, ==, 1024); g_assert_true(endptr == str + 354); } @@ -2826,16 +2826,16 @@ static void test_qemu_strtosz_invalid(void) g_assert_cmpuint(res, ==, 0); g_assert_true(endptr == str); - /* FIXME Fraction tail can cause ERANGE overflow */ + /* Fraction tail can cause ERANGE overflow */ str = "15.9999999999999999999999999999999999999999999999999999E"; endptr = str; res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); - g_assert_cmpint(err, ==, 0 /* FIXME -ERANGE */); - g_assert_cmpuint(res, ==, 15ULL * EiB /* FIXME 0 */); - g_assert_true(endptr == str + 56 /* FIXME str */); + g_assert_cmpint(err, ==, -ERANGE); + g_assert_cmpuint(res, ==, 0); + g_assert_true(endptr == str + 56); - /* FIXME ERANGE underflow in the fraction tail should matter for 'B' */ + /* ERANGE underflow in the fraction tail matters for 'B' */ str = "1." "00000000000000000000000000000000000000000000000000" "00000000000000000000000000000000000000000000000000" @@ -2848,9 +2848,9 @@ static void test_qemu_strtosz_invalid(void) endptr = str; res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); - g_assert_cmpint(err, ==, 0 /* FIXME -EINVAL */); - g_assert_cmpuint(res, ==, 1 /* FIXME 0 */); - g_assert_true(endptr == str + 354 /* FIXME str */); + g_assert_cmpint(err, ==, -EINVAL); + g_assert_cmpuint(res, ==, 0); + g_assert_true(endptr == str); /* No hex fractions */ str = "0x1.8k"; @@ -3045,14 +3045,14 @@ static void test_qemu_strtosz_trailing(void) g_assert_cmpint(err, ==, -EINVAL); g_assert_cmpuint(res, ==, 0); - /* FIXME should stop parse after 'e'. No floating point exponents */ + /* Parse stops at 'e', which is not a floating point exponent */ str = "1.5e1k"; endptr = NULL; res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); - g_assert_cmpint(err, ==, -EINVAL /* FIXME 0 */); - g_assert_cmpuint(res, ==, 0 /* FIXME EiB * 1.5 */); - g_assert_true(endptr == str /* FIXME + 4 */); + g_assert_cmpint(err, ==, 0); + g_assert_cmpuint(res, ==, EiB * 1.5); + g_assert_true(endptr == str + 4); res = 0xbaadf00d; err = qemu_strtosz(str, NULL, &res); @@ -3063,23 +3063,22 @@ static void test_qemu_strtosz_trailing(void) endptr = NULL; res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); - g_assert_cmpint(err, ==, -EINVAL /* FIXME 0 */); - g_assert_cmpuint(res, ==, 0 /* FIXME EiB * 1.5 */); - g_assert_true(endptr == str /* FIXME + 4 */); + g_assert_cmpint(err, ==, 0); + g_assert_cmpuint(res, ==, EiB * 1.5); + g_assert_true(endptr == str + 4); res = 0xbaadf00d; err = qemu_strtosz(str, NULL, &res); g_assert_cmpint(err, ==, -EINVAL); g_assert_cmpuint(res, ==, 0); - /* FIXME overflow in fraction is buggy */ str = "1.5E999"; endptr = NULL; res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, 0); - g_assert_cmpuint(res, ==, 1 /* FIXME EiB * 1.5 */); - g_assert(endptr == str + 2 /* FIXME + 4 */); + g_assert_cmpuint(res, ==, EiB * 1.5); + g_assert_true(endptr == str + 4); res = 0xbaadf00d; err = qemu_strtosz(str, NULL, &res); diff --git a/util/cutils.c b/util/cutils.c index 0e056a27a44..d1dfbc69d16 100644 --- a/util/cutils.c +++ b/util/cutils.c @@ -194,14 +194,17 @@ static int64_t suffix_mul(char suffix, int64_t unit) * - 12345 - decimal, scale determined by @default_suffix and @unit * - 12345{bBkKmMgGtTpPeE} - decimal, scale determined by suffix and @unit * - 12345.678{kKmMgGtTpPeE} - decimal, scale determined by suffix, and - * fractional portion is truncated to byte + * fractional portion is truncated to byte, either side of . may be empty * - 0x7fEE - hexadecimal, unit determined by @default_suffix * * The following are intentionally not supported - * - hex with scaling suffix, such as 0x20M - * - octal, such as 08 - * - fractional hex, such as 0x1.8 - * - floating point exponents, such as 1e3 + * - hex with scaling suffix, such as 0x20M (0x1b is 27, not 1) + * - octal, such as 08 (parsed as decimal instead) + * - binary, such as 0b1000 (parsed as 0b with trailing garbage "1000") + * - fractional hex, such as 0x1.8 (parsed as 0 with trailing garbage "x1.8") + * - floating point exponents, such as 1e3 (parsed as 1e with trailing + * garbage "3") or 0x1p3 (parsed as 1 with trailing garbage "p3") + * - non-finite values, such as inf or NaN * * The end pointer will be returned in *end, if not NULL. If there is * no fraction, the input can be decimal or hexadecimal; if there is a @@ -220,22 +223,17 @@ static int do_strtosz(const char *nptr, const char **end, uint64_t *result) { int retval; - const char *endptr, *f; + const char *endptr; unsigned char c; - uint64_t val, valf = 0; + uint64_t val = 0, valf = 0; int64_t mul; /* Parse integral portion as decimal. */ retval = qemu_strtou64(nptr, &endptr, 10, &val); - if (retval) { + if (retval == -ERANGE || !nptr) { goto out; } - if (memchr(nptr, '-', endptr - nptr) != NULL) { - endptr = nptr; - retval = -EINVAL; - goto out; - } - if (val == 0 && (*endptr == 'x' || *endptr == 'X')) { + if (retval == 0 && 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); if (retval) { @@ -246,27 +244,66 @@ static int do_strtosz(const char *nptr, const char **end, retval = -EINVAL; goto out; } - } else if (*endptr == '.') { + } else if (*endptr == '.' || (endptr == nptr && strchr(nptr, '.'))) { /* * Input looks like a fraction. Make sure even 1.k works - * without fractional digits. If we see an exponent, treat - * the entire input as invalid instead. + * without fractional digits. strtod tries to treat 'e' as an + * exponent, but we want to treat it as a scaling suffix; + * doing this requires modifying a copy of the fraction. */ - double fraction; + double fraction = 0.0; - f = endptr; - retval = qemu_strtod_finite(f, &endptr, &fraction); - if (retval) { + if (retval == 0 && *endptr == '.' && !isdigit(endptr[1])) { + /* If we got here, we parsed at least one digit already. */ endptr++; - } else if (memchr(f, 'e', endptr - f) || memchr(f, 'E', endptr - f)) { - endptr = nptr; - retval = -EINVAL; - goto out; } else { - /* Extract into a 64-bit fixed-point fraction. */ + char *e; + const char *tail; + g_autofree char *copy = g_strdup(endptr); + + e = strchr(copy, 'e'); + if (e) { + *e = '\0'; + } + e = strchr(copy, 'E'); + if (e) { + *e = '\0'; + } + /* + * If this is a floating point, we are guaranteed that '.' + * appears before any possible digits in copy. If it is + * not a floating point, strtod will fail. Either way, + * there is now no exponent in copy, so if it parses, we + * know 0.0 <= abs(result) <= 1.0 (after rounding), and + * ERANGE is only possible on underflow which is okay. + */ + retval = qemu_strtod_finite(copy, &tail, &fraction); + endptr += tail - copy; + } + + /* Extract into a 64-bit fixed-point fraction. */ + if (fraction == 1.0) { + if (val == UINT64_MAX) { + retval = -ERANGE; + goto out; + } + val++; + } else if (retval == -ERANGE) { + /* See comments above about underflow */ + valf = 1; + retval = 0; + } else { valf = (uint64_t)(fraction * 0x1p64); } } + if (retval) { + goto out; + } + if (memchr(nptr, '-', endptr - nptr) != NULL) { + endptr = nptr; + retval = -EINVAL; + goto out; + } c = *endptr; mul = suffix_mul(c, unit); if (mul > 0) {