From patchwork Wed Dec 10 18:24:50 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 25477 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 34213C3257 for ; Wed, 10 Dec 2025 18:24:58 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 70BBE614B1; Wed, 10 Dec 2025 19:24:57 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="emN24TlB"; 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 6306061499 for ; Wed, 10 Dec 2025 19:24:56 +0100 (CET) Received: from pb-laptop.local (185.221.143.114.nat.pool.zt.hu [185.221.143.114]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 8B742667 for ; Wed, 10 Dec 2025 19:24:54 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1765391094; bh=f+axXcjIFbepvFCLuQk6x/9lgaaRikKBN/Fv1IgQ3NM=; h=From:To:Subject:Date:From; b=emN24TlBWqr0x6DEkw0hxKH80bwOTB7nBL1vf3XHBJQvxeg4z0BM5wUzm40eYXzDC dy+BfXLNCdgpV1iETOjvDm+G1DXOJo95FUfPvSfbS56OszWcjeFZQy0/gVssucxhDb MOXWnM22HB1ePPE3HJEHsUqDRPt8DbE18cOGVDRg= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Subject: [PATCH v1] libcamera: controls: ControlList::set(): Ensure init list size and type Date: Wed, 10 Dec 2025 19:24:50 +0100 Message-ID: <20251210182450.2782689-1-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.52.0 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 initializer list should have the same type as the control, otherwise the `ControlValue` will have a type different from what is indicated in the template parameter of the control. This leads to an assertion failure when the control is later retrieved. Ensure that by using the same template parameter for the init list. The same applies to the size of the init list. If the size of the control is static, then the init list must have the same size. Ensure that by adding an `assert()` for statically sized controls. For example, previously list.set(controls::FrameDurationLimits, { 1000, 2000 }); would lead to an assertion failure when the control was retrieved since the deduced type in the init list would be `int`, making the `ControlValue` be of `ControlTypeInteger32` instead of the expected `ControlTypeInteger64`. Signed-off-by: Barnabás Pőcze --- include/libcamera/controls.h | 10 +++++++--- src/libcamera/controls.cpp | 3 ++- test/controls/control_list.cpp | 14 ++++++++++++++ 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h index c970e4b7b8..2a891f4f0c 100644 --- a/include/libcamera/controls.h +++ b/include/libcamera/controls.h @@ -457,14 +457,18 @@ public: val->set(value); } - template - void set(const Control> &ctrl, const std::initializer_list &value) + template + void set(const Control> &ctrl, + const std::initializer_list> &value) { + if constexpr (Size != dynamic_extent) + assert(Size == value.size()); + ControlValue *val = find(ctrl.id()); if (!val) return; - val->set(Span, Size>{ value.begin(), value.size() }); + val->set(Span{ value.begin(), value.size() }); } const ControlValue &get(unsigned int id) const; diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp index 1e1b49e6bd..90f89947ce 100644 --- a/src/libcamera/controls.cpp +++ b/src/libcamera/controls.cpp @@ -1074,7 +1074,8 @@ bool ControlList::contains(unsigned int id) const */ /** - * \fn ControlList::set(const Control> &ctrl, const std::initializer_list &value) + * \fn ControlList::set(const Control> &ctrl, + * const std::initializer_list> &value) * \copydoc ControlList::set(const Control &ctrl, const V &value) */ diff --git a/test/controls/control_list.cpp b/test/controls/control_list.cpp index e27325c30c..0e6b0bd27c 100644 --- a/test/controls/control_list.cpp +++ b/test/controls/control_list.cpp @@ -246,6 +246,20 @@ protected: return TestFail; } + ControlList list2; + + /* Check deduced type of init list */ + { + const auto &ctrl = controls::FrameDurationLimits; + + list2.set(ctrl, { 1, 2 }); + + if (list2.get(ctrl.id()).type() != static_cast(ctrl).type()) { + cout << "Type of init list has been incorrectly deduced"; + return TestFail; + } + } + return TestPass; } };