]> git.alsa-project.org Git - alsa-lib.git/commitdiff
topology: do not call strtol directly
authorJaroslav Kysela <perex@perex.cz>
Tue, 2 Nov 2021 09:43:27 +0000 (10:43 +0100)
committerJaroslav Kysela <perex@perex.cz>
Tue, 2 Nov 2021 09:45:51 +0000 (10:45 +0100)
Introduce safe_strtol_base() function and redirects all
strtol calls there. Also, improve error and value handling
in callers.

BugLink: https://github.com/alsa-project/alsa-lib/issues/187
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
src/topology/data.c
src/topology/ops.c
src/topology/parser.c

index 0546d63e478c91aea54dc62d4fbf1632f4432b5d..972b4b7ac94b3879ca7fb6145a88b0668c90cb60 100644 (file)
@@ -414,12 +414,8 @@ static int write_hex(char *buf, char *str, int width)
        void *p = &val;
 
         errno = 0;
-       val = strtol(str, NULL, 16);
-
-       if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN))
-               || (errno != 0 && val == 0)) {
+       if (safe_strtol_base(str, &val, 16) < 0)
                return -EINVAL;
-        }
 
        switch (width) {
        case 1:
index da175608557a895aa58f40defab14f02ce8e6db0..daab357781783d8bf42087a4863c650507f42332 100644 (file)
@@ -34,15 +34,22 @@ static const struct map_elem control_map[] = {
 
 static int lookup_ops(const char *c)
 {
-       unsigned int i;
+       int i;
+       long ret;
 
-       for (i = 0; i < ARRAY_SIZE(control_map); i++) {
+       for (i = 0; i < (int)ARRAY_SIZE(control_map); i++) {
                if (strcmp(control_map[i].name, c) == 0)
                        return control_map[i].id;
        }
 
        /* cant find string name in our table so we use its ID number */
-       return strtol(c, NULL, 0);
+       i = safe_strtol(c, &ret);
+       if (i < 0) {
+               SNDERR("wrong kcontrol ops value string '%s'", c);
+               return i;
+       }
+
+       return ret;
 }
 
 const char *tplg_ops_name(int type)
index f34de01bdc53b054982efeb993cf2493667970aa..01c95afaa13f2226fac6215b2ab0e15c2dd20e6e 100644 (file)
 #include "list.h"
 #include "tplg_local.h"
 
+/*
+ * Safe strtol call
+ */
+int safe_strtol_base(const char *str, long *val, int base)
+{
+       char *end;
+       long v;
+       if (!*str)
+               return -EINVAL;
+       errno = 0;
+       v = strtol(str, &end, base);
+       if (errno)
+               return -errno;
+       if (*end)
+               return -EINVAL;
+       *val = v;
+       return 0;
+}
+
 /*
  * Get integer value
  */
@@ -35,24 +54,23 @@ int tplg_get_integer(snd_config_t *n, int *val, int base)
                err = snd_config_get_integer(n, &lval);
                if (err < 0)
                        return err;
-               if (lval < INT_MIN || lval > INT_MAX)
-                       return -ERANGE;
-               *val = lval;
-               return err;
+               goto __retval;
        case SND_CONFIG_TYPE_STRING:
                err = snd_config_get_string(n, &str);
                if (err < 0)
                        return err;
-               errno = 0;
-               *val = strtol(str, NULL, base);
-               if (errno == ERANGE)
-                       return -ERANGE;
-               if (errno && *val == 0)
-                       return -EINVAL;
-               return 0;
+               err = safe_strtol_base(str, &lval, base);
+               if (err < 0)
+                       return err;
+               goto __retval;
        default:
                return -EINVAL;
        }
+  __retval:
+       if (lval < INT_MIN || lval > INT_MAX)
+               return -ERANGE;
+       *val = lval;
+       return 0;
 }
 
 /*