X-Git-Url: https://git.kernel.dk/?a=blobdiff_plain;f=parse.c;h=483a62f680cf8ba3dde1982afdb9aea63bcd6d73;hb=ad3e7e97780c406fca5afa56239b2a6b71cf6277;hp=196de1553b8e4992d499c299bc7bb7efa1f5be61;hpb=a69c9b57ddcff0cfaa481578ecbc4630b27b971f;p=fio.git diff --git a/parse.c b/parse.c index 196de155..483a62f6 100644 --- a/parse.c +++ b/parse.c @@ -373,12 +373,16 @@ int str_to_decimal(const char *str, long long *val, int kilo, void *data, #endif if (rc == 1) { + char *endptr; + if (strstr(str, "0x") || strstr(str, "0X")) base = 16; else base = 10; - *val = strtoll(str, NULL, base); + *val = strtoll(str, &endptr, base); + if (*val == 0 && endptr == str) + return 1; if (*val == LONG_MAX && errno == ERANGE) return 1; } @@ -506,6 +510,33 @@ static const char *opt_type_name(const struct fio_option *o) return "OPT_UNKNOWN?"; } +static bool val_too_large(const struct fio_option *o, unsigned long long val, + bool is_uint) +{ + if (!o->maxval) + return false; + + if (is_uint) { + if ((int) val < 0) + return (int) val > (int) o->maxval; + return (unsigned int) val > o->maxval; + } + + return val > o->maxval; +} + +static bool val_too_small(const struct fio_option *o, unsigned long long val, + bool is_uint) +{ + if (!o->minval) + return false; + + if (is_uint) + return (int) val < o->minval; + + return val < o->minval; +} + static int __handle_option(const struct fio_option *o, const char *ptr, void *data, int first, int more, int curr) { @@ -575,8 +606,7 @@ static int __handle_option(const struct fio_option *o, const char *ptr, if (!is_time && o->is_time) is_time = o->is_time; - tmp[sizeof(tmp) - 1] = '\0'; - strncpy(tmp, ptr, sizeof(tmp) - 1); + snprintf(tmp, sizeof(tmp), "%s", ptr); p = strchr(tmp, ','); if (p) *p = '\0'; @@ -595,12 +625,12 @@ static int __handle_option(const struct fio_option *o, const char *ptr, return 1; } - if (o->maxval && ull > o->maxval) { + if (val_too_large(o, ull, o->type == FIO_OPT_INT)) { log_err("%s: max value out of range: %llu" " (%llu max)\n", o->name, ull, o->maxval); return 1; } - if (o->minval && ull < o->minval) { + if (val_too_small(o, ull, o->type == FIO_OPT_INT)) { log_err("%s: min value out of range: %lld" " (%d min)\n", o->name, ull, o->minval); return 1; @@ -802,8 +832,7 @@ static int __handle_option(const struct fio_option *o, const char *ptr, char tmp[128]; char *p1, *p2; - tmp[sizeof(tmp) - 1] = '\0'; - strncpy(tmp, ptr, sizeof(tmp) - 1); + snprintf(tmp, sizeof(tmp), "%s", ptr); /* Handle bsrange with separate read,write values: */ p1 = strchr(tmp, ',');