This is an automatic generated email to let you know that the following patch 
were queued at the 
http://git.linuxtv.org/cgit.cgi/v4l-utils.git tree:

Subject: v4l2-ctl: Fix failure on controls starting with a digit
Author:  Benjamin Mugnier <[email protected]>
Date:    Mon Dec 15 10:44:28 2025 +0100

Specifically querying the 3a_lock control from v4l2-ctl fails :

  $ v4l2-ctl -C 3a_lock
  VIDIOC_G_EXT_CTRLS: failed: Invalid argument
  : 0

A similar issue occurs when setting the control :

  $ v4l2-ctl -c 3a_lock=0
  VIDIOC_S_EXT_CTRLS: failed: Invalid argument
  Error setting controls: Invalid argument

This does not happen with other controls. Internally, v4l2-ctl parses
its arguments in order and differentiates a control name from a value
using this check :

  if (isdigit(s[0]))

This means if the argument starts with a letter, it is a control
name; otherwise, it is a control value. This works well for all controls
except for 3a_lock, which starts with a digit and is wrongly detected as
a control value.

Currently, 3a_lock is the only control that starts with a digit.

Introduce is_valid_number() to check if a string contains only digits,
and therefore would return false when parsing '3a_lock'. Use
is_valid_number() for control get and set operations.

Signed-off-by: Benjamin Mugnier <[email protected]>
Signed-off-by: Hans Verkuil <[email protected]>

 utils/v4l2-ctl/v4l2-ctl-common.cpp | 8 ++++----
 utils/v4l2-ctl/v4l2-ctl.h          | 9 +++++++++
 2 files changed, 13 insertions(+), 4 deletions(-)

---

http://git.linuxtv.org/cgit.cgi/v4l-utils.git/commit/?id=eaa9f46fc304c18be2fa9141061592c5003a2da5
diff --git a/utils/v4l2-ctl/v4l2-ctl-common.cpp 
b/utils/v4l2-ctl/v4l2-ctl-common.cpp
index 32dbe9de7162..87e361412c53 100644
--- a/utils/v4l2-ctl/v4l2-ctl-common.cpp
+++ b/utils/v4l2-ctl/v4l2-ctl-common.cpp
@@ -1000,7 +1000,7 @@ void common_process_controls(cv4l_fd &fd)
        find_controls(fd);
        for (const auto &get_ctrl : get_ctrls) {
                std::string s = get_ctrl;
-               if (isdigit(s[0])) {
+               if (is_valid_number(s)) {
                        __u32 id = strtoul(s.c_str(), nullptr, 0);
                        if (ctrl_id2str.find(id) != ctrl_id2str.end())
                                s = ctrl_id2str[id];
@@ -1012,7 +1012,7 @@ void common_process_controls(cv4l_fd &fd)
        }
        for (const auto &set_ctrl : set_ctrls) {
                std::string s = set_ctrl.first;
-               if (isdigit(s[0])) {
+               if (is_valid_number(s)) {
                        __u32 id = strtoul(s.c_str(), nullptr, 0);
                        if (ctrl_id2str.find(id) != ctrl_id2str.end())
                                s = ctrl_id2str[id];
@@ -1212,7 +1212,7 @@ void common_set(cv4l_fd &_fd)
                memset(&ctrls, 0, sizeof(ctrls));
                for (const auto &set_ctrl : set_ctrls) {
                        std::string s = set_ctrl.first;
-                       if (isdigit(s[0])) {
+                       if (is_valid_number(s)) {
                                __u32 id = strtoul(s.c_str(), nullptr, 0);
                                s = ctrl_id2str[id];
                        }
@@ -1359,7 +1359,7 @@ void common_get(cv4l_fd &_fd)
                memset(&ctrls, 0, sizeof(ctrls));
                for (const auto &get_ctrl : get_ctrls) {
                        std::string s = get_ctrl;
-                       if (isdigit(s[0])) {
+                       if (is_valid_number(s)) {
                                __u32 id = strtoul(s.c_str(), nullptr, 0);
                                s = ctrl_id2str[id];
                        }
diff --git a/utils/v4l2-ctl/v4l2-ctl.h b/utils/v4l2-ctl/v4l2-ctl.h
index b0d42110ca0f..ae6f43f37c1c 100644
--- a/utils/v4l2-ctl/v4l2-ctl.h
+++ b/utils/v4l2-ctl/v4l2-ctl.h
@@ -4,6 +4,7 @@
 #include <cstdint>
 #include <linux/videodev2.h>
 #include <linux/v4l2-subdev.h>
+#include <stdlib.h>
 #include <v4l-getsubopt.h>
 
 #include <v4l2-info.h>
@@ -331,6 +332,14 @@ static inline bool subscribe_event(cv4l_fd &fd, __u32 type)
        return !fd.subscribe_event(sub);
 }
 
+static inline bool is_valid_number(const std::string &str)
+{
+       char *endptr;
+       strtoul(str.c_str(), &endptr, 0);
+
+       return *endptr == '\0';
+}
+
 #define doioctl(n, r, p) doioctl_name(n, r, p, #r)
 
 #define info(fmt, args...)                     \
_______________________________________________
linuxtv-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to