Add check for OPT_LEN_MAX being too small
[fio.git] / parse.c
diff --git a/parse.c b/parse.c
index 78218615b79246a50c02107b7907ef747dd95476..d44d13082c91dd8951cbe0be7edf2c51dd73d7e0 100644 (file)
--- a/parse.c
+++ b/parse.c
@@ -162,9 +162,19 @@ int str_to_decimal(const char *str, long long *val, int kilo, void *data)
        if (*val == LONG_MAX && errno == ERANGE)
                return 1;
 
-       if (kilo)
-               *val *= get_mult_bytes(str[len - 1], data);
-       else
+       if (kilo) {
+               const char *p;
+               /*
+                * if the last char is 'b' or 'B', the user likely used
+                * "1gb" instead of just "1g". If the second to last is also
+                * a letter, adjust.
+                */
+               p = str + len - 1;
+               if ((*p == 'b' || *p == 'B') && isalpha(*(p - 1)))
+                       --p;
+
+               *val *= get_mult_bytes(*p, data);
+       } else
                *val *= get_mult_time(str[len - 1]);
 
        return 0;
@@ -610,6 +620,11 @@ static char *option_dup_subs(const char *opt)
        ssize_t nchr = OPT_LEN_MAX;
        size_t envlen;
 
+       if (strlen(in) + 1 > OPT_LEN_MAX) {
+               fprintf(stderr, "OPT_LEN_MAX (%d) is too small\n", OPT_LEN_MAX);
+               return NULL;
+       }
+
        in[OPT_LEN_MAX] = '\0';
        strncpy(in, opt, OPT_LEN_MAX);
 
@@ -649,6 +664,8 @@ int parse_option(const char *opt, struct fio_option *options, void *data)
        char *post, *tmp;
 
        tmp = option_dup_subs(opt);
+       if (!tmp)
+               return 1;
 
        o = get_option(tmp, options, &post);
        if (!o) {