From patchwork Fri Oct 31 11:52:14 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 24931 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 9A9ABC3259 for ; Fri, 31 Oct 2025 11:52:28 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 60058609D7; Fri, 31 Oct 2025 12:52:26 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="CWg1xxoz"; 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 46A0A60947 for ; Fri, 31 Oct 2025 12:52:23 +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 7EC0611DD; Fri, 31 Oct 2025 12:50:32 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1761911432; bh=QAoPfSzdtnw/jpHJmkeH87f+rmQW83cTY5Jnv4DtdRI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=CWg1xxozXfKALv1qaFWzs7lAyI/gsKg/E9LQR7gyCO6JBEVC6e22ydsVtaJwbAsp1 U5WHfUVQFSS1UM+ru/5LxXP5bLTP7DXoxTidmRZLLA4+iqZtjDr1g1F0RZ+agJnyGo yM6gRdELsaXil9JSH6SYh0/WcG/cVLpYsDHxPdx8= 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 11:52:14 +0000 Message-ID: <20251031115216.3776845-2-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20251031115216.3776845-1-kieran.bingham@ideasonboard.com> References: <20251031115216.3776845-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 11:52:15 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 24932 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 C13E0C32CE for ; Fri, 31 Oct 2025 11:52:29 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id BAC00609DE; Fri, 31 Oct 2025 12:52:27 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="CWdXaMpc"; 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 96196600CC for ; Fri, 31 Oct 2025 12:52:23 +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 C985215D2; Fri, 31 Oct 2025 12:50:32 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1761911432; bh=p5oQ5BPJu1xDQNkES/R6dHAS5DWX9MdWCogu7uLPwh0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=CWdXaMpcJjLNYYEzhHYQwMaDjdvAvBCTpbdMk5d0Ue7v0qbYZ6NhPf8gsd+BE1ttw k80tfHrUfoSt8BJtNpQORrRhNOxA1lcAG9gKH3DNBpgd3MSQt6Fg29Q8wT3yAFSblQ JgWEJMjsy40OqB3q+TjIFqt0soJigEFX/aqYgXVo= 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 11:52:15 +0000 Message-ID: <20251031115216.3776845-3-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20251031115216.3776845-1-kieran.bingham@ideasonboard.com> References: <20251031115216.3776845-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: Barnabás Pőcze --- include/libcamera/base/utils.h | 68 ++++++---------------------------- src/libcamera/base/utils.cpp | 2 +- test/meson.build | 2 +- 3 files changed, 14 insertions(+), 58 deletions(-) diff --git a/include/libcamera/base/utils.h b/include/libcamera/base/utils.h index d32bd1cd62e0..555da71f124b 100644 --- a/include/libcamera/base/utils.h +++ b/include/libcamera/base/utils.h @@ -78,67 +78,23 @@ 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> * = nullptr> + hex(T value, unsigned int width = sizeof(T) * 2) + : v(static_cast>(value)), + w(width) + { + } }; 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 hex &h); +#else +template> * = nullptr> +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..446c9a05e96d 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 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']}, ]