From patchwork Fri Oct 31 20:38:53 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 24934 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id C9DF7C32D4 for ; Fri, 31 Oct 2025 20:39:04 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id F15E060A7C; Fri, 31 Oct 2025 21:39:01 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="cF13yKpm"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 4FD98609C0 for ; Fri, 31 Oct 2025 21:38:58 +0100 (CET) Received: from charm.hippo-penny.ts.net (cpc89244-aztw30-2-0-cust6594.18-1.cable.virginm.net [86.31.185.195]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 2D9DE1690; Fri, 31 Oct 2025 21:37:07 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1761943027; bh=ljkA3+FYyVQWVeCGtWgaq1+REDvu1ffIsUAAe6sX9r8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=cF13yKpmscdoDQTlcO+rErz3jckb6uBm8ldBWBzr/rVrkU+olYQEhJZh55A0+wXnl PwTbkyzsXrfshURaQVhNzeEt8mXvUhnCKIKa06q7kCc7KWG2XfRIORJsGMervqnlse jIjh2D49CoLngij0pJijY77cv+tuPBe1PyBoJ5VA= From: Kieran Bingham To: libcamera devel Cc: Kieran Bingham , =?utf-8?q?Barnab?= =?utf-8?b?w6FzIFDFkWN6ZQ==?= , Laurent Pinchart Subject: [PATCH v3 1/2] test: utils: Validate hex sign extension Date: Fri, 31 Oct 2025 20:38:53 +0000 Message-ID: <20251031203854.19021-2-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20251031203854.19021-1-kieran.bingham@ideasonboard.com> References: <20251031203854.19021-1-kieran.bingham@ideasonboard.com> MIME-Version: 1.0 X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Converting strings to hex stores data in a uint64_t. This can incorrectly sign extend if the type being converted is signed. Provide tests to be sure that the signed conversion is correct. This is known to fail, so report as expected failure. Reviewed-by: Barnabás Pőcze Reviewed-by: Laurent Pinchart Signed-off-by: Kieran Bingham --- test/meson.build | 2 +- test/utils.cpp | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/test/meson.build b/test/meson.build index 52f04364e4fc..96c4477f04b2 100644 --- a/test/meson.build +++ b/test/meson.build @@ -73,7 +73,7 @@ internal_tests = [ {'name': 'timer-fail', 'sources': ['timer-fail.cpp'], 'should_fail': true}, {'name': 'timer-thread', 'sources': ['timer-thread.cpp']}, {'name': 'unique-fd', 'sources': ['unique-fd.cpp']}, - {'name': 'utils', 'sources': ['utils.cpp']}, + {'name': 'utils', 'sources': ['utils.cpp'], 'should_fail': true}, {'name': 'vector', 'sources': ['vector.cpp']}, {'name': 'yaml-parser', 'sources': ['yaml-parser.cpp']}, ] diff --git a/test/utils.cpp b/test/utils.cpp index ca2e4f3b3e85..b5ce94e5e912 100644 --- a/test/utils.cpp +++ b/test/utils.cpp @@ -218,6 +218,23 @@ protected: os << utils::hex(static_cast(0x42), 1) << " "; ref += "0x42 "; + os << utils::hex(static_cast(-1)) << " "; + ref += "0xff "; + os << utils::hex(static_cast(-1)) << " "; + ref += "0xff "; + os << utils::hex(static_cast(-1)) << " "; + ref += "0xffff "; + os << utils::hex(static_cast(-1)) << " "; + ref += "0xffff "; + os << utils::hex(static_cast(-1)) << " "; + ref += "0xffffffff "; + os << utils::hex(static_cast(-1)) << " "; + ref += "0xffffffff "; + os << utils::hex(static_cast(-1)) << " "; + ref += "0xffffffffffffffff "; + os << utils::hex(static_cast(-1)) << " "; + ref += "0xffffffffffffffff "; + std::string s = os.str(); if (s != ref) { cerr << "utils::hex() test failed, expected '" << ref From patchwork Fri Oct 31 20:38:54 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 24935 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 18427C32DB for ; Fri, 31 Oct 2025 20:39:06 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 6360E609E0; Fri, 31 Oct 2025 21:39:03 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="STC9q6B2"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 8A44360947 for ; Fri, 31 Oct 2025 21:38:58 +0100 (CET) Received: from charm.hippo-penny.ts.net (cpc89244-aztw30-2-0-cust6594.18-1.cable.virginm.net [86.31.185.195]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 78F7D1691; Fri, 31 Oct 2025 21:37:07 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1761943027; bh=1bm/SqHeujeQ4kcDobrPwskmL3V7FCo1abcyR3IOGsc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=STC9q6B2m9KgJTC3tWCi5i2/0SuuS1SviUx9rHJgbD3sU2fZy9YDyjr4Jlg52Dxue L6fuBGt0Bc8aRnB9ggKiBoYmX3bHivB8fD884CL+exloaBpKDPHBKwJ/ConiYuAVR1 PnRyBoyfpOQlu0H1AwWAZJHxkpulVvBgNjaOopms= From: Kieran Bingham To: libcamera devel Cc: Kieran Bingham , =?utf-8?q?Barnab?= =?utf-8?b?w6FzIFDFkWN6ZQ==?= Subject: [PATCH v3 2/2] libcamera: base: utils: Simplify hex adaptor Date: Fri, 31 Oct 2025 20:38:54 +0000 Message-ID: <20251031203854.19021-3-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20251031203854.19021-1-kieran.bingham@ideasonboard.com> References: <20251031203854.19021-1-kieran.bingham@ideasonboard.com> MIME-Version: 1.0 X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The libcamera hex string adaptor specifies and casts each type specifically to map the size of each type. This needlessly repeats itself for each type and further more has a bug with signed integer extension which causes values such as 0x80 to be printed as 0xffffffffffffff80 instead. Remove the template specialisations for each type, and unify with a single templated constructor of the struct hex trait. Suggested-by: Barnabás Pőcze Signed-off-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- include/libcamera/base/utils.h | 68 +++++++--------------------------- src/libcamera/base/utils.cpp | 3 +- test/meson.build | 2 +- 3 files changed, 17 insertions(+), 56 deletions(-) diff --git a/include/libcamera/base/utils.h b/include/libcamera/base/utils.h index d32bd1cd62e0..0b7407f7724b 100644 --- a/include/libcamera/base/utils.h +++ b/include/libcamera/base/utils.h @@ -77,70 +77,30 @@ using time_point = std::chrono::steady_clock::time_point; struct timespec duration_to_timespec(const duration &value); std::string time_point_to_string(const time_point &time); -#ifndef __DOXYGEN__ -struct _hex { +namespace details { + +struct hex { uint64_t v; unsigned int w; }; +template +constexpr unsigned int hex_width() +{ + return sizeof(T) * 2; +} + std::basic_ostream> & -operator<<(std::basic_ostream> &stream, const _hex &h); -#endif +operator<<(std::basic_ostream> &stream, const hex &h); -template::value> * = nullptr> -_hex hex(T value, unsigned int width = 0); +} /* namespace details */ -#ifndef __DOXYGEN__ -template<> -inline _hex hex(int8_t value, unsigned int width) +template> * = nullptr> +details::hex hex(T value, unsigned int width = details::hex_width()) { - return { static_cast(value), width ? width : 2 }; + return { static_cast>(value), width }; } -template<> -inline _hex hex(uint8_t value, unsigned int width) -{ - return { static_cast(value), width ? width : 2 }; -} - -template<> -inline _hex hex(int16_t value, unsigned int width) -{ - return { static_cast(value), width ? width : 4 }; -} - -template<> -inline _hex hex(uint16_t value, unsigned int width) -{ - return { static_cast(value), width ? width : 4 }; -} - -template<> -inline _hex hex(int32_t value, unsigned int width) -{ - return { static_cast(value), width ? width : 8 }; -} - -template<> -inline _hex hex(uint32_t value, unsigned int width) -{ - return { static_cast(value), width ? width : 8 }; -} - -template<> -inline _hex hex(int64_t value, unsigned int width) -{ - return { static_cast(value), width ? width : 16 }; -} - -template<> -inline _hex hex(uint64_t value, unsigned int width) -{ - return { static_cast(value), width ? width : 16 }; -} -#endif - size_t strlcpy(char *dst, const char *src, size_t size); #ifndef __DOXYGEN__ diff --git a/src/libcamera/base/utils.cpp b/src/libcamera/base/utils.cpp index cb9fe0049c83..65d9181c927f 100644 --- a/src/libcamera/base/utils.cpp +++ b/src/libcamera/base/utils.cpp @@ -187,7 +187,8 @@ std::string time_point_to_string(const time_point &time) } std::basic_ostream> & -operator<<(std::basic_ostream> &stream, const _hex &h) +details::operator<<(std::basic_ostream> &stream, + const details::hex &h) { stream << "0x"; diff --git a/test/meson.build b/test/meson.build index 96c4477f04b2..52f04364e4fc 100644 --- a/test/meson.build +++ b/test/meson.build @@ -73,7 +73,7 @@ internal_tests = [ {'name': 'timer-fail', 'sources': ['timer-fail.cpp'], 'should_fail': true}, {'name': 'timer-thread', 'sources': ['timer-thread.cpp']}, {'name': 'unique-fd', 'sources': ['unique-fd.cpp']}, - {'name': 'utils', 'sources': ['utils.cpp'], 'should_fail': true}, + {'name': 'utils', 'sources': ['utils.cpp']}, {'name': 'vector', 'sources': ['vector.cpp']}, {'name': 'yaml-parser', 'sources': ['yaml-parser.cpp']}, ]