diff options
author | Xin LI <delphij@FreeBSD.org> | 2023-06-13 04:08:32 +0000 |
---|---|---|
committer | Xin LI <delphij@FreeBSD.org> | 2023-06-13 04:08:32 +0000 |
commit | 08300d849485bd6231d3a18cb430cab4279edef3 (patch) | |
tree | dcec6fece3797322669ac2f6ec421f229f2adc68 /lib/libutil/expand_number.c | |
parent | bdc81eeda05d3af80254f6aac95759b07f13f2b7 (diff) | |
download | src-08300d849485bd6231d3a18cb430cab4279edef3.tar.gz src-08300d849485bd6231d3a18cb430cab4279edef3.zip |
expand_number: Tighten check of unit.
The current code silently ignores characters after the unit as long
the unit themselves were recognized. This commit makes expand_number(3)
to fail with EINVAL if buf did not terminate after the unit character.
Historically, the function accepts and ignores "B" as a SI unit, this
behavior is preserved and e.g. KB, MB are still accepted as aliases of
K and M, document this behavior in the manual page.
While I am there, also write a few test cases to validate the behavior.
Reviewed-by: emaste
MFC-after: 2 weeks
Differential Revision: https://reviews.freebsd.org/D40482
Diffstat (limited to 'lib/libutil/expand_number.c')
-rw-r--r-- | lib/libutil/expand_number.c | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/lib/libutil/expand_number.c b/lib/libutil/expand_number.c index f34db013ff18..61b73039f3bd 100644 --- a/lib/libutil/expand_number.c +++ b/lib/libutil/expand_number.c @@ -76,6 +76,8 @@ expand_number(const char *buf, uint64_t *num) shift = 10; break; case 'b': + shift = 0; + break; case '\0': /* No unit. */ *num = number; return (0); @@ -85,6 +87,18 @@ expand_number(const char *buf, uint64_t *num) return (-1); } + /* + * Treat 'b' as an ignored suffix for all unit except 'b', + * otherwise there should be no remaining character(s). + */ + endptr++; + if (shift != 0 && tolower((unsigned char)*endptr) == 'b') + endptr++; + if (*endptr != '\0') { + errno = EINVAL; + return (-1); + } + if ((number << shift) >> shift != number) { /* Overflow */ errno = ERANGE; |