From patchwork Thu Oct 30 18:11:26 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 24927 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 90B3CBE080 for ; Thu, 30 Oct 2025 18:11:36 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id BEBAF6096B; Thu, 30 Oct 2025 19:11:33 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="eYqOXR1A"; 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 3AF77608DC for ; Thu, 30 Oct 2025 19:11:32 +0100 (CET) Received: from Monstersaurus.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 EEEFC1E27; Thu, 30 Oct 2025 19:09:41 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1761847782; bh=jRhoJSp/kzBTNZeZPWG6Ej4dxxjJyb3GOBy7QzXDScI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=eYqOXR1AhfDsvFZrD/taOf6+b/IxKAS8lVLO/giUlrZnmJfjiCbwAfG/A1wzj/Fbg iPu/M7j6/kthRivP7rqmhJo4Atkuep9Yf0/4E5s5f1eaLSrQXJZyAuA/wdiZ5xaQhd 3abyPf3F89c+b9m07wQeuPhX/c/jlAUYC6aQkISA= From: Kieran Bingham To: libcamera devel Cc: Kieran Bingham Subject: [PATCH v2 1/2] test: utils: Validate hex sign extension Date: Thu, 30 Oct 2025 18:11:26 +0000 Message-ID: <20251030181127.1059501-2-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20251030181127.1059501-1-kieran.bingham@ideasonboard.com> References: <20251030181127.1059501-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. Signed-off-by: Kieran Bingham Reviewed-by: Barnabás Pőcze Reviewed-by: Laurent Pinchart --- 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 Thu Oct 30 18:11:27 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 24928 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 ABCC9C32CE for ; Thu, 30 Oct 2025 18:11:37 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 265F260967; Thu, 30 Oct 2025 19:11:35 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="UainzoJb"; 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 5965C608DF for ; Thu, 30 Oct 2025 19:11:32 +0100 (CET) Received: from Monstersaurus.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 36AF41E33; Thu, 30 Oct 2025 19:09:42 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1761847782; bh=/ST+k2N8Z6PCUh+tw/WoKA/TdEXlroxmkP8nKiH2gvQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=UainzoJbyH/Vhuz5SbFPb/mOg982Djd2EbHn12JVkZ7YyZamqPAfmEXT5cVTbzK9K 76fzu/CHynUfiWyWdq11PsBa7i7mbf19Dpm1ReIpfQiZg6Dz/ojM7pjNc2Z0MePVZs VBcNxWshAywO5hssrDsdlBMxuUjotLxn3jOq3+iE= From: Kieran Bingham To: libcamera devel Cc: Kieran Bingham Subject: [PATCH v2 2/2] libcamera: base: utils: Simplify hex adaptor Date: Thu, 30 Oct 2025 18:11:27 +0000 Message-ID: <20251030181127.1059501-3-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20251030181127.1059501-1-kieran.bingham@ideasonboard.com> References: <20251030181127.1059501-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. Signed-off-by: Kieran Bingham --- include/libcamera/base/utils.h | 66 ++++++---------------------------- src/libcamera/base/utils.cpp | 2 +- test/meson.build | 2 +- 3 files changed, 12 insertions(+), 58 deletions(-) diff --git a/include/libcamera/base/utils.h b/include/libcamera/base/utils.h index d32bd1cd62e0..3b3da7b2a887 100644 --- a/include/libcamera/base/utils.h +++ b/include/libcamera/base/utils.h @@ -78,67 +78,21 @@ struct timespec duration_to_timespec(const duration &value); std::string time_point_to_string(const time_point &time); #ifndef __DOXYGEN__ -struct _hex { +struct hex { uint64_t v; unsigned int w; + + template::value> * = nullptr> + hex(T value, unsigned int width = 0) + : v(static_cast>(value)), + w(width ? width : sizeof(T) * 2) + { } }; std::basic_ostream> & -operator<<(std::basic_ostream> &stream, const _hex &h); -#endif - -template::value> * = nullptr> -_hex hex(T value, unsigned int width = 0); - -#ifndef __DOXYGEN__ -template<> -inline _hex hex(int8_t value, unsigned int width) -{ - return { static_cast(value), width ? width : 2 }; -} - -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 }; -} +operator<<(std::basic_ostream> &stream, const struct hex &h); +#else +void hex(T value, unsigned int width = 0); #endif size_t strlcpy(char *dst, const char *src, size_t size); diff --git a/src/libcamera/base/utils.cpp b/src/libcamera/base/utils.cpp index cb9fe0049c83..db868be224a2 100644 --- a/src/libcamera/base/utils.cpp +++ b/src/libcamera/base/utils.cpp @@ -187,7 +187,7 @@ std::string time_point_to_string(const time_point &time) } std::basic_ostream> & -operator<<(std::basic_ostream> &stream, const _hex &h) +operator<<(std::basic_ostream> &stream, const struct 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']}, ]