From 94d6c2b5088292e101da3e1d078e155a5af32f56 Mon Sep 17 00:00:00 2001 From: Tokunori Ikegami Date: Sun, 14 May 2023 17:39:00 +0900 Subject: [PATCH] util: Fix suffix_si_parse to parse no decimal point but suffix value correctly For example create-ns command --ncap-si paramter value 800G parsed to 0 as invalid value. Signed-off-by: Tokunori Ikegami --- unit/test-suffix-si-parse.c | 6 +++++ util/suffix.c | 50 +++++++++++++++++++++++++++---------- 2 files changed, 43 insertions(+), 13 deletions(-) diff --git a/unit/test-suffix-si-parse.c b/unit/test-suffix-si-parse.c index bc924552..54cff0e6 100644 --- a/unit/test-suffix-si-parse.c +++ b/unit/test-suffix-si-parse.c @@ -43,6 +43,12 @@ static struct tonum_test tonum_tests[] = { { "2,33", 0, -EINVAL }, { "3..3", 0, -EINVAL }, { "123.12MM", 0, -EINVAL }, + { "800G", 800000000000, 0 }, + { "800GG", 0, -EINVAL }, + { "800G800", 0, -EINVAL }, + { "800.0G", 800000000000, 0 }, + { "800.G", 0, -EINVAL }, + { "800.", 0, -EINVAL }, }; void tonum_test(struct tonum_test *test) diff --git a/util/suffix.c b/util/suffix.c index 8ed080d4..f010f3b6 100644 --- a/util/suffix.c +++ b/util/suffix.c @@ -40,6 +40,7 @@ #include #include #include +#include static struct si_suffix { long double magnitude; @@ -68,11 +69,26 @@ const char *suffix_si_get(double *value) return suffix; } +static bool suffix_si_check(const char val) +{ + int i; + struct si_suffix *s; + + for (i = 0; i < ARRAY_SIZE(si_suffixes); i++) { + s = &si_suffixes[i]; + + if (val == *s->suffix) + return true; + } + + return false; +} + int suffix_si_parse(const char *str, char **endptr, uint64_t *val) { - unsigned long long num, frac; + unsigned long long num, frac = 0; char *sep, *tmp; - int frac_len, len, i; + int frac_len = 0, len, i; num = strtoull(str, endptr, 0); if (str == *endptr || @@ -93,23 +109,31 @@ int suffix_si_parse(const char *str, char **endptr, uint64_t *val) len = 0; for (i = 0; i < len; i++) { + if (suffix_si_check((*endptr)[i])) + break; if (((*endptr)[i] == '\0') || (*endptr)[i] != sep[i]) return -EINVAL; } - *endptr += len; - tmp = *endptr; - /* extract the digits after decimal point */ - frac = strtoull(tmp, endptr, 0); - if (tmp == *endptr || - ((frac == ULLONG_MAX) && errno == ERANGE)) - return -EINVAL; + if (suffix_si_check((*endptr)[i])) { + if ((*endptr)[i + 1] != '\0') + return -EINVAL; + } else { + *endptr += len; + tmp = *endptr; + + /* extract the digits after decimal point */ + frac = strtoull(tmp, endptr, 0); + if (tmp == *endptr || + ((frac == ULLONG_MAX) && errno == ERANGE)) + return -EINVAL; - /* test that we have max one character as suffix */ - if ((*endptr)[0] != '\0' && (*endptr)[1] != '\0') - return -EINVAL; + /* test that we have max one character as suffix */ + if ((*endptr)[0] != '\0' && (*endptr)[1] != '\0') + return -EINVAL; - frac_len = *endptr - tmp; + frac_len = *endptr - tmp; + } for (i = 0; i < ARRAY_SIZE(si_suffixes); i++) { struct si_suffix *s = &si_suffixes[i]; -- 2.39.3