Show a patch.

GET /api/1.1/patches/25477/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 25477,
    "url": "https://patchwork.libcamera.org/api/1.1/patches/25477/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/25477/",
    "project": {
        "id": 1,
        "url": "https://patchwork.libcamera.org/api/1.1/projects/1/?format=api",
        "name": "libcamera",
        "link_name": "libcamera",
        "list_id": "libcamera_core",
        "list_email": "libcamera-devel@lists.libcamera.org",
        "web_url": "",
        "scm_url": "",
        "webscm_url": ""
    },
    "msgid": "<20251210182450.2782689-1-barnabas.pocze@ideasonboard.com>",
    "date": "2025-12-10T18:24:50",
    "name": "[v1] libcamera: controls: ControlList::set(): Ensure init list size and type",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "9431ffa6e165ea67d0a0bf7d8ec22a7b3fa77073",
    "submitter": {
        "id": 216,
        "url": "https://patchwork.libcamera.org/api/1.1/people/216/?format=api",
        "name": "Barnabás Pőcze",
        "email": "barnabas.pocze@ideasonboard.com"
    },
    "delegate": null,
    "mbox": "https://patchwork.libcamera.org/patch/25477/mbox/",
    "series": [
        {
            "id": 5651,
            "url": "https://patchwork.libcamera.org/api/1.1/series/5651/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=5651",
            "date": "2025-12-10T18:24:50",
            "name": "[v1] libcamera: controls: ControlList::set(): Ensure init list size and type",
            "version": 1,
            "mbox": "https://patchwork.libcamera.org/series/5651/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/25477/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/25477/checks/",
    "tags": {},
    "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 34213C3257\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 10 Dec 2025 18:24:58 +0000 (UTC)",
            "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 70BBE614B1;\n\tWed, 10 Dec 2025 19:24:57 +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 6306061499\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 10 Dec 2025 19:24:56 +0100 (CET)",
            "from pb-laptop.local (185.221.143.114.nat.pool.zt.hu\n\t[185.221.143.114])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 8B742667\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 10 Dec 2025 19:24:54 +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=\"emN24TlB\"; dkim-atps=neutral",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1765391094;\n\tbh=f+axXcjIFbepvFCLuQk6x/9lgaaRikKBN/Fv1IgQ3NM=;\n\th=From:To:Subject:Date:From;\n\tb=emN24TlBWqr0x6DEkw0hxKH80bwOTB7nBL1vf3XHBJQvxeg4z0BM5wUzm40eYXzDC\n\tdy+BfXLNCdgpV1iETOjvDm+G1DXOJo95FUfPvSfbS56OszWcjeFZQy0/gVssucxhDb\n\tMOXWnM22HB1ePPE3HJEHsUqDRPt8DbE18cOGVDRg=",
        "From": "=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>",
        "To": "libcamera-devel@lists.libcamera.org",
        "Subject": "[PATCH v1] libcamera: controls: ControlList::set(): Ensure init list\n\tsize 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",
        "Content-Type": "text/plain; charset=UTF-8",
        "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>"
    },
    "content": "The initializer list should have the same type as the control, otherwise\nthe `ControlValue` will have a type different from what is indicated in\nthe template parameter of the control. This leads to an assertion failure\nwhen the control is later retrieved. Ensure that by using the same template\nparameter for the init list.\n\nThe same applies to the size of the init list. If the size of the control\nis static, then the init list must have the same size. Ensure that by\nadding an `assert()` for statically sized controls.\n\nFor example, previously\n\n  list.set(controls::FrameDurationLimits, { 1000, 2000 });\n\nwould lead to an assertion failure when the control was retrieved since the\ndeduced type in the init list would be `int`, making the `ControlValue` be of\n`ControlTypeInteger32` instead of the expected `ControlTypeInteger64`.\n\nSigned-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>\n---\n include/libcamera/controls.h   | 10 +++++++---\n src/libcamera/controls.cpp     |  3 ++-\n test/controls/control_list.cpp | 14 ++++++++++++++\n 3 files changed, 23 insertions(+), 4 deletions(-)",
    "diff": "diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h\nindex c970e4b7b8..2a891f4f0c 100644\n--- a/include/libcamera/controls.h\n+++ b/include/libcamera/controls.h\n@@ -457,14 +457,18 @@ public:\n \t\tval->set<T>(value);\n \t}\n \n-\ttemplate<typename T, typename V, size_t Size>\n-\tvoid set(const Control<Span<T, Size>> &ctrl, const std::initializer_list<V> &value)\n+\ttemplate<typename T, size_t Size>\n+\tvoid set(const Control<Span<T, Size>> &ctrl,\n+\t\t const std::initializer_list<std::remove_cv_t<T>> &value)\n \t{\n+\t\tif constexpr (Size != dynamic_extent)\n+\t\t\tassert(Size == value.size());\n+\n \t\tControlValue *val = find(ctrl.id());\n \t\tif (!val)\n \t\t\treturn;\n \n-\t\tval->set(Span<const typename std::remove_cv_t<V>, Size>{ value.begin(), value.size() });\n+\t\tval->set(Span<const T, Size>{ value.begin(), value.size() });\n \t}\n \n \tconst ControlValue &get(unsigned int id) const;\ndiff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp\nindex 1e1b49e6bd..90f89947ce 100644\n--- a/src/libcamera/controls.cpp\n+++ b/src/libcamera/controls.cpp\n@@ -1074,7 +1074,8 @@ bool ControlList::contains(unsigned int id) const\n  */\n \n /**\n- * \\fn ControlList::set(const Control<Span<T, Size>> &ctrl, const std::initializer_list<V> &value)\n+ * \\fn ControlList::set(const Control<Span<T, Size>> &ctrl,\n+ *                      const std::initializer_list<std::remove_cv_t<T>> &value)\n  * \\copydoc ControlList::set(const Control<T> &ctrl, const V &value)\n  */\n \ndiff --git a/test/controls/control_list.cpp b/test/controls/control_list.cpp\nindex e27325c30c..0e6b0bd27c 100644\n--- a/test/controls/control_list.cpp\n+++ b/test/controls/control_list.cpp\n@@ -246,6 +246,20 @@ protected:\n \t\t\treturn TestFail;\n \t\t}\n \n+\t\tControlList list2;\n+\n+\t\t/* Check deduced type of init list */\n+\t\t{\n+\t\t\tconst auto &ctrl = controls::FrameDurationLimits;\n+\n+\t\t\tlist2.set(ctrl, { 1, 2 });\n+\n+\t\t\tif (list2.get(ctrl.id()).type() != static_cast<const ControlId &>(ctrl).type()) {\n+\t\t\t\tcout << \"Type of init list has been incorrectly deduced\";\n+\t\t\t\treturn TestFail;\n+\t\t\t}\n+\t\t}\n+\n \t\treturn TestPass;\n \t}\n };\n",
    "prefixes": [
        "v1"
    ]
}