[{"id":36529,"web_url":"https://patchwork.libcamera.org/comment/36529/","msgid":"<176167625645.2233196.14594362948401521161@ping.linuxembedded.co.uk>","date":"2025-10-28T18:30:56","subject":"Re: [PATCH] libcamera: base: utils: Prevent hex signed extension","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"Quoting Kieran Bingham (2025-10-28 18:29:36)\n> When converting signed values to hex strings using the utils::hex\n> helpers, signed negative values get sign extended to the larger 64 bit\n> type.\n> \n> This causes values such as 0x80 to be printed as 0xffffffffffffff80\n> instead.\n> \n> Resolve this by first converting all signed integer types to an unsigned\n> type of the same size before extending to the larger type.\n> \n\nPossibly for posterity and to highlight in release notes this could be:\n\nFixes: 45bd1f20f6a9 (\"libcamera: base: utils: Implement hex() for 8-bit and 16-bit values\")\n\n> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> ---\n>  include/libcamera/base/utils.h | 6 +++---\n>  1 file changed, 3 insertions(+), 3 deletions(-)\n> \n> diff --git a/include/libcamera/base/utils.h b/include/libcamera/base/utils.h\n> index cb8caaa9bacc..fdc3fd91f1b6 100644\n> --- a/include/libcamera/base/utils.h\n> +++ b/include/libcamera/base/utils.h\n> @@ -95,7 +95,7 @@ _hex hex(T value, unsigned int width = 0);\n>  template<>\n>  inline _hex hex<int8_t>(int8_t value, unsigned int width)\n>  {\n> -       return { static_cast<uint64_t>(value), width ? width : 2 };\n> +       return { static_cast<uint64_t>(static_cast<uint8_t>(value)), width ? width : 2 };\n>  }\n>  \n>  template<>\n> @@ -107,7 +107,7 @@ inline _hex hex<uint8_t>(uint8_t value, unsigned int width)\n>  template<>\n>  inline _hex hex<int16_t>(int16_t value, unsigned int width)\n>  {\n> -       return { static_cast<uint64_t>(value), width ? width : 4 };\n> +       return { static_cast<uint64_t>(static_cast<uint16_t>(value)), width ? width : 4 };\n>  }\n>  \n>  template<>\n> @@ -119,7 +119,7 @@ inline _hex hex<uint16_t>(uint16_t value, unsigned int width)\n>  template<>\n>  inline _hex hex<int32_t>(int32_t value, unsigned int width)\n>  {\n> -       return { static_cast<uint64_t>(value), width ? width : 8 };\n> +       return { static_cast<uint64_t>(static_cast<uint32_t>(value)), width ? width : 8 };\n>  }\n>  \n>  template<>\n> -- \n> 2.51.0\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 5EE2DC3259\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 28 Oct 2025 18:31:01 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 1A22560810;\n\tTue, 28 Oct 2025 19:31:01 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 519B7606DE\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 28 Oct 2025 19:30:59 +0100 (CET)","from pendragon.ideasonboard.com\n\t(cpc89244-aztw30-2-0-cust6594.18-1.cable.virginm.net [86.31.185.195])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id AB3ED13BE\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 28 Oct 2025 19:29:10 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"TsW3OX/z\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1761676150;\n\tbh=Y/4ublPpHKxR9qdptFJz5yScIBYd5PmnRehVZ6kPyZk=;\n\th=In-Reply-To:References:Subject:From:Cc:To:Date:From;\n\tb=TsW3OX/zmQ13C9/gbpVC6bTlpzAJQS7yVJQUKMZM8RoEI7FAAcuRAG59YMpUEnzkH\n\tDTOnQu1g2XPoW7kS4Hwz4/WUCtL+4nJW/vG7Qtb5ntZy8n+XKoJOD1o08sLt4R0IbX\n\tIYNbpBbKE7TGpodX5q/igRmkL4/mIy88fFHflIiY=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<20251028182936.14362-1-kieran.bingham@ideasonboard.com>","References":"<20251028182936.14362-1-kieran.bingham@ideasonboard.com>","Subject":"Re: [PATCH] libcamera: base: utils: Prevent hex signed extension","From":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Cc":"","To":"libcamera devel <libcamera-devel@lists.libcamera.org>","Date":"Tue, 28 Oct 2025 18:30:56 +0000","Message-ID":"<176167625645.2233196.14594362948401521161@ping.linuxembedded.co.uk>","User-Agent":"alot/0.9.1","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":36530,"web_url":"https://patchwork.libcamera.org/comment/36530/","msgid":"<30a34706-e31b-4620-8eba-dd7f9dfd1903@ideasonboard.com>","date":"2025-10-29T09:03:55","subject":"Re: [PATCH] libcamera: base: utils: Prevent hex signed extension","submitter":{"id":216,"url":"https://patchwork.libcamera.org/api/people/216/","name":"Barnabás Pőcze","email":"barnabas.pocze@ideasonboard.com"},"content":"Hi\n\n2025. 10. 28. 19:29 keltezéssel, Kieran Bingham írta:\n> When converting signed values to hex strings using the utils::hex\n> helpers, signed negative values get sign extended to the larger 64 bit\n> type.\n> \n> This causes values such as 0x80 to be printed as 0xffffffffffffff80\n> instead.\n> \n> Resolve this by first converting all signed integer types to an unsigned\n> type of the same size before extending to the larger type.\n> \n> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> ---\n>   include/libcamera/base/utils.h | 6 +++---\n>   1 file changed, 3 insertions(+), 3 deletions(-)\n> \n> diff --git a/include/libcamera/base/utils.h b/include/libcamera/base/utils.h\n> index cb8caaa9bacc..fdc3fd91f1b6 100644\n> --- a/include/libcamera/base/utils.h\n> +++ b/include/libcamera/base/utils.h\n> @@ -95,7 +95,7 @@ _hex hex(T value, unsigned int width = 0);\n>   template<>\n>   inline _hex hex<int8_t>(int8_t value, unsigned int width)\n>   {\n> -\treturn { static_cast<uint64_t>(value), width ? width : 2 };\n> +\treturn { static_cast<uint64_t>(static_cast<uint8_t>(value)), width ? width : 2 };\n\nI think you can omit the `static_cast<uint64_t>()` here and below.\n\nIt seems to me there are also tests, so it should not be too\ncomplicated to check the new behaviour.\n\n\nRegards,\nBarnabás Pőcze\n\n>   }\n>   \n>   template<>\n> @@ -107,7 +107,7 @@ inline _hex hex<uint8_t>(uint8_t value, unsigned int width)\n>   template<>\n>   inline _hex hex<int16_t>(int16_t value, unsigned int width)\n>   {\n> -\treturn { static_cast<uint64_t>(value), width ? width : 4 };\n> +\treturn { static_cast<uint64_t>(static_cast<uint16_t>(value)), width ? width : 4 };\n>   }\n>   \n>   template<>\n> @@ -119,7 +119,7 @@ inline _hex hex<uint16_t>(uint16_t value, unsigned int width)\n>   template<>\n>   inline _hex hex<int32_t>(int32_t value, unsigned int width)\n>   {\n> -\treturn { static_cast<uint64_t>(value), width ? width : 8 };\n> +\treturn { static_cast<uint64_t>(static_cast<uint32_t>(value)), width ? width : 8 };\n>   }\n>   \n>   template<>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 5B494BE080\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 29 Oct 2025 09:04:03 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 4B9AD6081F;\n\tWed, 29 Oct 2025 10:04:02 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 8DF9B600CC\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 29 Oct 2025 10:04:00 +0100 (CET)","from [192.168.33.28] (185.182.215.162.nat.pool.zt.hu\n\t[185.182.215.162])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id D2A7B4C6A;\n\tWed, 29 Oct 2025 10:02:10 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"Hzlo6u/Q\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1761728531;\n\tbh=378B4x6fLFSZZ5rm0bdoPBPFjfVr00/LINwZogTrESg=;\n\th=Date:Subject:To:References:From:In-Reply-To:From;\n\tb=Hzlo6u/Qyfigpv7QZHq0pebnqbEpA0903sRgfjiBeP32Uu3tYFjBOjHSgQH7LnrOH\n\ttkVF+O/hnBkw/74WzGGKUbFp45QQ+yQiU8kh7Gl1iv6rpHy3EdqaPY8qzBbqd2FH9y\n\tsqJElbNIomJ5QiZLf4UwlTqO/0fxkq6IRs5oF754=","Message-ID":"<30a34706-e31b-4620-8eba-dd7f9dfd1903@ideasonboard.com>","Date":"Wed, 29 Oct 2025 10:03:55 +0100","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH] libcamera: base: utils: Prevent hex signed extension","To":"Kieran Bingham <kieran.bingham@ideasonboard.com>,\n\tlibcamera devel <libcamera-devel@lists.libcamera.org>","References":"<20251028182936.14362-1-kieran.bingham@ideasonboard.com>","From":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>","Content-Language":"en-US, hu-HU","In-Reply-To":"<20251028182936.14362-1-kieran.bingham@ideasonboard.com>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"8bit","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":36531,"web_url":"https://patchwork.libcamera.org/comment/36531/","msgid":"<20251029092221.GB797@pendragon.ideasonboard.com>","date":"2025-10-29T09:22:21","subject":"Re: [PATCH] libcamera: base: utils: Prevent hex signed extension","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"On Wed, Oct 29, 2025 at 10:03:55AM +0100, Barnabás Pőcze wrote:\n> 2025. 10. 28. 19:29 keltezéssel, Kieran Bingham írta:\n> > When converting signed values to hex strings using the utils::hex\n> > helpers, signed negative values get sign extended to the larger 64 bit\n> > type.\n> > \n> > This causes values such as 0x80 to be printed as 0xffffffffffffff80\n> > instead.\n> > \n> > Resolve this by first converting all signed integer types to an unsigned\n> > type of the same size before extending to the larger type.\n> > \n> > Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> > ---\n> >   include/libcamera/base/utils.h | 6 +++---\n> >   1 file changed, 3 insertions(+), 3 deletions(-)\n> > \n> > diff --git a/include/libcamera/base/utils.h b/include/libcamera/base/utils.h\n> > index cb8caaa9bacc..fdc3fd91f1b6 100644\n> > --- a/include/libcamera/base/utils.h\n> > +++ b/include/libcamera/base/utils.h\n> > @@ -95,7 +95,7 @@ _hex hex(T value, unsigned int width = 0);\n> >   template<>\n> >   inline _hex hex<int8_t>(int8_t value, unsigned int width)\n> >   {\n> > -\treturn { static_cast<uint64_t>(value), width ? width : 2 };\n> > +\treturn { static_cast<uint64_t>(static_cast<uint8_t>(value)), width ? width : 2 };\n> \n> I think you can omit the `static_cast<uint64_t>()` here and below.\n\nIt looks we could simplify the implementation with the following\n(untested) code that replaces all specializations.\n\ntemplate<typename T,\n\t std::enable_if_t<std::is_integral<T>::value &&\n\t\t\t  !std::is_same_v<T, bool>> * = nullptr>\n_hex hex(T value, unsigned int width = 0)\n{\n\treturn {\n\t\tstatic_cast<std::make_unsigned_t<T>>(value),\n\t\twidth ? width : static_cast<unsigned int>(sizeof(T)) * 2\n\t};\n}\n\n> It seems to me there are also tests, so it should not be too\n> complicated to check the new behaviour.\n> \n> >   }\n> >   \n> >   template<>\n> > @@ -107,7 +107,7 @@ inline _hex hex<uint8_t>(uint8_t value, unsigned int width)\n> >   template<>\n> >   inline _hex hex<int16_t>(int16_t value, unsigned int width)\n> >   {\n> > -\treturn { static_cast<uint64_t>(value), width ? width : 4 };\n> > +\treturn { static_cast<uint64_t>(static_cast<uint16_t>(value)), width ? width : 4 };\n> >   }\n> >   \n> >   template<>\n> > @@ -119,7 +119,7 @@ inline _hex hex<uint16_t>(uint16_t value, unsigned int width)\n> >   template<>\n> >   inline _hex hex<int32_t>(int32_t value, unsigned int width)\n> >   {\n> > -\treturn { static_cast<uint64_t>(value), width ? width : 8 };\n> > +\treturn { static_cast<uint64_t>(static_cast<uint32_t>(value)), width ? width : 8 };\n> >   }\n> >   \n> >   template<>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 8FFFEBE080\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 29 Oct 2025 09:22:37 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 710D460849;\n\tWed, 29 Oct 2025 10:22:36 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id CF2D4600CC\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 29 Oct 2025 10:22:34 +0100 (CET)","from pendragon.ideasonboard.com (unknown [193.209.96.36])\n\tby perceval.ideasonboard.com (Postfix) with UTF8SMTPSA id 47889520;\n\tWed, 29 Oct 2025 10:20:45 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"YhGhLxUt\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1761729645;\n\tbh=smUK+K+eqIkzOtnZJ0QEot+c5E/zf4JKSTFi0UYhTQE=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=YhGhLxUtuBoUlb/jliyDr42zh3SklaKEzXWetEnncisc31/a+kzMcxlhyGj9c7Ood\n\t9d/ftVDdrOnKNXNWnlNjQgKfCS5H1EDX/xapBI7LI99HvYwpCIITepj81GEulKW//q\n\tiEd1O3YIlNcP3OzA8ns35VznNgLoGmFJi/6/KdkA=","Date":"Wed, 29 Oct 2025 11:22:21 +0200","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>","Cc":"Kieran Bingham <kieran.bingham@ideasonboard.com>,\n\tlibcamera devel <libcamera-devel@lists.libcamera.org>","Subject":"Re: [PATCH] libcamera: base: utils: Prevent hex signed extension","Message-ID":"<20251029092221.GB797@pendragon.ideasonboard.com>","References":"<20251028182936.14362-1-kieran.bingham@ideasonboard.com>\n\t<30a34706-e31b-4620-8eba-dd7f9dfd1903@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<30a34706-e31b-4620-8eba-dd7f9dfd1903@ideasonboard.com>","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":36532,"web_url":"https://patchwork.libcamera.org/comment/36532/","msgid":"<40a4f293-215d-403f-8774-645cff55406b@ideasonboard.com>","date":"2025-10-29T09:28:18","subject":"Re: [PATCH] libcamera: base: utils: Prevent hex signed extension","submitter":{"id":216,"url":"https://patchwork.libcamera.org/api/people/216/","name":"Barnabás Pőcze","email":"barnabas.pocze@ideasonboard.com"},"content":"2025. 10. 29. 10:22 keltezéssel, Laurent Pinchart írta:\n> On Wed, Oct 29, 2025 at 10:03:55AM +0100, Barnabás Pőcze wrote:\n>> 2025. 10. 28. 19:29 keltezéssel, Kieran Bingham írta:\n>>> When converting signed values to hex strings using the utils::hex\n>>> helpers, signed negative values get sign extended to the larger 64 bit\n>>> type.\n>>>\n>>> This causes values such as 0x80 to be printed as 0xffffffffffffff80\n>>> instead.\n>>>\n>>> Resolve this by first converting all signed integer types to an unsigned\n>>> type of the same size before extending to the larger type.\n>>>\n>>> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n>>> ---\n>>>    include/libcamera/base/utils.h | 6 +++---\n>>>    1 file changed, 3 insertions(+), 3 deletions(-)\n>>>\n>>> diff --git a/include/libcamera/base/utils.h b/include/libcamera/base/utils.h\n>>> index cb8caaa9bacc..fdc3fd91f1b6 100644\n>>> --- a/include/libcamera/base/utils.h\n>>> +++ b/include/libcamera/base/utils.h\n>>> @@ -95,7 +95,7 @@ _hex hex(T value, unsigned int width = 0);\n>>>    template<>\n>>>    inline _hex hex<int8_t>(int8_t value, unsigned int width)\n>>>    {\n>>> -\treturn { static_cast<uint64_t>(value), width ? width : 2 };\n>>> +\treturn { static_cast<uint64_t>(static_cast<uint8_t>(value)), width ? width : 2 };\n>>\n>> I think you can omit the `static_cast<uint64_t>()` here and below.\n> \n> It looks we could simplify the implementation with the following\n> (untested) code that replaces all specializations.\n> \n> template<typename T,\n> \t std::enable_if_t<std::is_integral<T>::value &&\n> \t\t\t  !std::is_same_v<T, bool>> * = nullptr>\n> _hex hex(T value, unsigned int width = 0)\n> {\n> \treturn {\n> \t\tstatic_cast<std::make_unsigned_t<T>>(value),\n> \t\twidth ? width : static_cast<unsigned int>(sizeof(T)) * 2\n> \t};\n> }\n\nYes, I agree. Or even more:\n\nstruct hex {\n   uint64_t v;\n   unsigned int w;\n\n   template<typename T, std::enable_if_t...>\n   hex(T value, unsigned int width = 0)\n     : v(static_cast<std::make_unsigned_t<T>>(value)),\n       w(width ? width : sizeof(T) * 2)\n   { }\n};\n\nand then one does not need a separate function at all.\n\n\n> \n>> It seems to me there are also tests, so it should not be too\n>> complicated to check the new behaviour.\n>>\n>>>    }\n>>>    \n>>>    template<>\n>>> @@ -107,7 +107,7 @@ inline _hex hex<uint8_t>(uint8_t value, unsigned int width)\n>>>    template<>\n>>>    inline _hex hex<int16_t>(int16_t value, unsigned int width)\n>>>    {\n>>> -\treturn { static_cast<uint64_t>(value), width ? width : 4 };\n>>> +\treturn { static_cast<uint64_t>(static_cast<uint16_t>(value)), width ? width : 4 };\n>>>    }\n>>>    \n>>>    template<>\n>>> @@ -119,7 +119,7 @@ inline _hex hex<uint16_t>(uint16_t value, unsigned int width)\n>>>    template<>\n>>>    inline _hex hex<int32_t>(int32_t value, unsigned int width)\n>>>    {\n>>> -\treturn { static_cast<uint64_t>(value), width ? width : 8 };\n>>> +\treturn { static_cast<uint64_t>(static_cast<uint32_t>(value)), width ? width : 8 };\n>>>    }\n>>>    \n>>>    template<>\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 6AC28C3259\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 29 Oct 2025 09:28:25 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 403286082E;\n\tWed, 29 Oct 2025 10:28:24 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id A1D10600CC\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 29 Oct 2025 10:28:22 +0100 (CET)","from [192.168.33.28] (185.182.215.162.nat.pool.zt.hu\n\t[185.182.215.162])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 50107446;\n\tWed, 29 Oct 2025 10:26:33 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"JNIMEg2O\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1761729993;\n\tbh=a7xwB39nrU1Zex0oikDkEDeyW/CuJda+tEymBU8sJCM=;\n\th=Date:Subject:To:Cc:References:From:In-Reply-To:From;\n\tb=JNIMEg2OpCTUCL0GQ5Uzldl3UcuglksarmmpffNOCwenjL9CFRKnGm+gES/GlyNii\n\tr7U/Fw5yS0Rjo6I3xNNL75qsTjzddkxbBw0FeWYaCg4qdNYe2qeqBTBHJQDqZJlVLn\n\tee/h0gL9W4VboHhTgZtaFa/OXzlha6TC+9qkUh2M=","Message-ID":"<40a4f293-215d-403f-8774-645cff55406b@ideasonboard.com>","Date":"Wed, 29 Oct 2025 10:28:18 +0100","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH] libcamera: base: utils: Prevent hex signed extension","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"Kieran Bingham <kieran.bingham@ideasonboard.com>,\n\tlibcamera devel <libcamera-devel@lists.libcamera.org>","References":"<20251028182936.14362-1-kieran.bingham@ideasonboard.com>\n\t<30a34706-e31b-4620-8eba-dd7f9dfd1903@ideasonboard.com>\n\t<20251029092221.GB797@pendragon.ideasonboard.com>","From":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>","Content-Language":"en-US, hu-HU","In-Reply-To":"<20251029092221.GB797@pendragon.ideasonboard.com>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"8bit","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":36533,"web_url":"https://patchwork.libcamera.org/comment/36533/","msgid":"<176173192469.3666756.12750565594893932467@ping.linuxembedded.co.uk>","date":"2025-10-29T09:58:44","subject":"Re: [PATCH] libcamera: base: utils: Prevent hex signed extension","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"Quoting Barnabás Pőcze (2025-10-29 09:28:18)\n> 2025. 10. 29. 10:22 keltezéssel, Laurent Pinchart írta:\n> > On Wed, Oct 29, 2025 at 10:03:55AM +0100, Barnabás Pőcze wrote:\n> >> 2025. 10. 28. 19:29 keltezéssel, Kieran Bingham írta:\n> >>> When converting signed values to hex strings using the utils::hex\n> >>> helpers, signed negative values get sign extended to the larger 64 bit\n> >>> type.\n> >>>\n> >>> This causes values such as 0x80 to be printed as 0xffffffffffffff80\n> >>> instead.\n> >>>\n> >>> Resolve this by first converting all signed integer types to an unsigned\n> >>> type of the same size before extending to the larger type.\n> >>>\n> >>> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> >>> ---\n> >>>    include/libcamera/base/utils.h | 6 +++---\n> >>>    1 file changed, 3 insertions(+), 3 deletions(-)\n> >>>\n> >>> diff --git a/include/libcamera/base/utils.h b/include/libcamera/base/utils.h\n> >>> index cb8caaa9bacc..fdc3fd91f1b6 100644\n> >>> --- a/include/libcamera/base/utils.h\n> >>> +++ b/include/libcamera/base/utils.h\n> >>> @@ -95,7 +95,7 @@ _hex hex(T value, unsigned int width = 0);\n> >>>    template<>\n> >>>    inline _hex hex<int8_t>(int8_t value, unsigned int width)\n> >>>    {\n> >>> -   return { static_cast<uint64_t>(value), width ? width : 2 };\n> >>> +   return { static_cast<uint64_t>(static_cast<uint8_t>(value)), width ? width : 2 };\n> >>\n> >> I think you can omit the `static_cast<uint64_t>()` here and below.\n> > \n> > It looks we could simplify the implementation with the following\n> > (untested) code that replaces all specializations.\n> > \n> > template<typename T,\n> >        std::enable_if_t<std::is_integral<T>::value &&\n> >                         !std::is_same_v<T, bool>> * = nullptr>\n> > _hex hex(T value, unsigned int width = 0)\n> > {\n> >       return {\n> >               static_cast<std::make_unsigned_t<T>>(value),\n> >               width ? width : static_cast<unsigned int>(sizeof(T)) * 2\n> >       };\n> > }\n> \n> Yes, I agree. Or even more:\n> \n> struct hex {\n>    uint64_t v;\n>    unsigned int w;\n> \n>    template<typename T, std::enable_if_t...>\n>    hex(T value, unsigned int width = 0)\n>      : v(static_cast<std::make_unsigned_t<T>>(value)),\n>        w(width ? width : sizeof(T) * 2)\n>    { }\n> };\n> \n> and then one does not need a separate function at all.\n\nThanks - parameterising this all out looks good.\n\nI agree on the tests too - I'll add a test case that failed for me - and\nthen convert.\n\n--\nKieran\n\n\n> \n> \n> > \n> >> It seems to me there are also tests, so it should not be too\n> >> complicated to check the new behaviour.\n> >>\n> >>>    }\n> >>>    \n> >>>    template<>\n> >>> @@ -107,7 +107,7 @@ inline _hex hex<uint8_t>(uint8_t value, unsigned int width)\n> >>>    template<>\n> >>>    inline _hex hex<int16_t>(int16_t value, unsigned int width)\n> >>>    {\n> >>> -   return { static_cast<uint64_t>(value), width ? width : 4 };\n> >>> +   return { static_cast<uint64_t>(static_cast<uint16_t>(value)), width ? width : 4 };\n> >>>    }\n> >>>    \n> >>>    template<>\n> >>> @@ -119,7 +119,7 @@ inline _hex hex<uint16_t>(uint16_t value, unsigned int width)\n> >>>    template<>\n> >>>    inline _hex hex<int32_t>(int32_t value, unsigned int width)\n> >>>    {\n> >>> -   return { static_cast<uint64_t>(value), width ? width : 8 };\n> >>> +   return { static_cast<uint64_t>(static_cast<uint32_t>(value)), width ? width : 8 };\n> >>>    }\n> >>>    \n> >>>    template<>\n> > \n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 3FC16BE080\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 29 Oct 2025 09:58:50 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 123E06082E;\n\tWed, 29 Oct 2025 10:58:49 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 39DB7600CC\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 29 Oct 2025 10:58:48 +0100 (CET)","from pendragon.ideasonboard.com\n\t(cpc89244-aztw30-2-0-cust6594.18-1.cable.virginm.net [86.31.185.195])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id DEA5A11DD;\n\tWed, 29 Oct 2025 10:56:58 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"T4TRBSi+\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1761731819;\n\tbh=8ZjWzwrVCZBq/CqyUGdrlrkaOVZVipRWG3shKYy1QDY=;\n\th=In-Reply-To:References:Subject:From:Cc:To:Date:From;\n\tb=T4TRBSi+hEY1Segaru735PhzymR2g+hqq96mDoWeW5JHADFxYak5vNY5LeunjObVc\n\t61jRXd6JHbuCgVyyiJxlGnyf5NtB2AgOcS/x9aCMZcxn8AiC/lR4leXmx6LwDRCM37\n\tRljXP9q353YrlCjyOMJCWh6rYEi7T9gvFdkoohZA=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<40a4f293-215d-403f-8774-645cff55406b@ideasonboard.com>","References":"<20251028182936.14362-1-kieran.bingham@ideasonboard.com>\n\t<30a34706-e31b-4620-8eba-dd7f9dfd1903@ideasonboard.com>\n\t<20251029092221.GB797@pendragon.ideasonboard.com>\n\t<40a4f293-215d-403f-8774-645cff55406b@ideasonboard.com>","Subject":"Re: [PATCH] libcamera: base: utils: Prevent hex signed extension","From":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Cc":"libcamera devel <libcamera-devel@lists.libcamera.org>","To":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>,\n\tLaurent Pinchart <laurent.pinchart@ideasonboard.com>","Date":"Wed, 29 Oct 2025 09:58:44 +0000","Message-ID":"<176173192469.3666756.12750565594893932467@ping.linuxembedded.co.uk>","User-Agent":"alot/0.9.1","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]