aboutsummaryrefslogtreecommitdiff
path: root/lib/libutil/expand_number.c
diff options
context:
space:
mode:
authorXin LI <delphij@FreeBSD.org>2023-06-13 04:08:32 +0000
committerXin LI <delphij@FreeBSD.org>2023-06-13 04:08:32 +0000
commit08300d849485bd6231d3a18cb430cab4279edef3 (patch)
treedcec6fece3797322669ac2f6ec421f229f2adc68 /lib/libutil/expand_number.c
parentbdc81eeda05d3af80254f6aac95759b07f13f2b7 (diff)
downloadsrc-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.c14
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;