]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
terminal-util: stop doing 0/upper bound check in tty_is_vc()
authorMike Yuan <me@yhndnzj.com>
Sun, 26 Jan 2025 00:32:42 +0000 (01:32 +0100)
committerMike Yuan <me@yhndnzj.com>
Sun, 26 Jan 2025 03:15:40 +0000 (04:15 +0100)
tty_is_vc() is more often than not used for simple "categorization"
than validity check. E.g. in logind, we first recognize the tty
"looks like vc", and then use vtnr_from_tty() where range check
is performed and vtnr is extracted. In such cases, we want to reject
invalid vtnr from clients rather than silently carry on, hence
let's remove bound check in tty_is_vc().

Fixes #36166
Replaces #36167 and #36175

src/basic/terminal-util.c

index eeeb6576239747aac7f47accc0cdd439e168eb32..2baf2830b176cced3ea81bc2e73c547094fcd520 100644 (file)
@@ -764,31 +764,25 @@ int make_console_stdio(void) {
         return 0;
 }
 
-bool tty_is_vc(const char *tty) {
+static int vtnr_from_tty_raw(const char *tty, unsigned *ret) {
         assert(tty);
 
-        return vtnr_from_tty(tty) >= 0;
-}
+        tty = skip_dev_prefix(tty);
 
-bool tty_is_console(const char *tty) {
-        assert(tty);
+        const char *e = startswith(tty, "tty");
+        if (!e)
+                return -EINVAL;
 
-        return streq(skip_dev_prefix(tty), "console");
+        return safe_atou(e, ret);
 }
 
 int vtnr_from_tty(const char *tty) {
+        unsigned u;
         int r;
 
         assert(tty);
 
-        tty = skip_dev_prefix(tty);
-
-        const char *e = startswith(tty, "tty");
-        if (!e)
-                return -EINVAL;
-
-        unsigned u;
-        r = safe_atou(e, &u);
+        r = vtnr_from_tty_raw(tty, &u);
         if (r < 0)
                 return r;
         if (!vtnr_is_valid(u))
@@ -797,6 +791,23 @@ int vtnr_from_tty(const char *tty) {
         return (int) u;
 }
 
+bool tty_is_vc(const char *tty) {
+        assert(tty);
+
+        /* NB: for >= 0 values no range check is conducted here, on the assumption that the caller will
+         * either extract vtnr through vtnr_from_tty() later where ERANGE would be reported, or doesn't care
+         * about whether it's strictly valid, but only asking "does this fall into the vt catogory?", for which
+         * "yes" seems to be a better answer. */
+
+        return vtnr_from_tty_raw(tty, /* ret = */ NULL) >= 0;
+}
+
+bool tty_is_console(const char *tty) {
+        assert(tty);
+
+        return streq(skip_dev_prefix(tty), "console");
+}
+
 int resolve_dev_console(char **ret) {
         int r;