Skip to content

Commit 9331bdb

Browse files
committed
Merge branch 'rs/config-unit-parsing'
The code to parse scaled numbers out of configuration files has been made more robust and also easier to follow. * rs/config-unit-parsing: config: simplify parsing of unit factors config: don't multiply in parse_unit_factor() config: use unsigned_mult_overflows to check for overflows
2 parents 7785f9b + 39c575c commit 9331bdb

File tree

1 file changed

+18
-21
lines changed

1 file changed

+18
-21
lines changed

config.c

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -861,22 +861,16 @@ static int git_parse_source(config_fn_t fn, void *data,
861861
return error_return;
862862
}
863863

864-
static int parse_unit_factor(const char *end, uintmax_t *val)
864+
static uintmax_t get_unit_factor(const char *end)
865865
{
866866
if (!*end)
867867
return 1;
868-
else if (!strcasecmp(end, "k")) {
869-
*val *= 1024;
870-
return 1;
871-
}
872-
else if (!strcasecmp(end, "m")) {
873-
*val *= 1024 * 1024;
874-
return 1;
875-
}
876-
else if (!strcasecmp(end, "g")) {
877-
*val *= 1024 * 1024 * 1024;
878-
return 1;
879-
}
868+
else if (!strcasecmp(end, "k"))
869+
return 1024;
870+
else if (!strcasecmp(end, "m"))
871+
return 1024 * 1024;
872+
else if (!strcasecmp(end, "g"))
873+
return 1024 * 1024 * 1024;
880874
return 0;
881875
}
882876

@@ -886,19 +880,20 @@ static int git_parse_signed(const char *value, intmax_t *ret, intmax_t max)
886880
char *end;
887881
intmax_t val;
888882
uintmax_t uval;
889-
uintmax_t factor = 1;
883+
uintmax_t factor;
890884

891885
errno = 0;
892886
val = strtoimax(value, &end, 0);
893887
if (errno == ERANGE)
894888
return 0;
895-
if (!parse_unit_factor(end, &factor)) {
889+
factor = get_unit_factor(end);
890+
if (!factor) {
896891
errno = EINVAL;
897892
return 0;
898893
}
899894
uval = val < 0 ? -val : val;
900-
uval *= factor;
901-
if (uval > max || (val < 0 ? -val : val) > uval) {
895+
if (unsigned_mult_overflows(factor, uval) ||
896+
factor * uval > max) {
902897
errno = ERANGE;
903898
return 0;
904899
}
@@ -915,21 +910,23 @@ static int git_parse_unsigned(const char *value, uintmax_t *ret, uintmax_t max)
915910
if (value && *value) {
916911
char *end;
917912
uintmax_t val;
918-
uintmax_t oldval;
913+
uintmax_t factor;
919914

920915
errno = 0;
921916
val = strtoumax(value, &end, 0);
922917
if (errno == ERANGE)
923918
return 0;
924-
oldval = val;
925-
if (!parse_unit_factor(end, &val)) {
919+
factor = get_unit_factor(end);
920+
if (!factor) {
926921
errno = EINVAL;
927922
return 0;
928923
}
929-
if (val > max || oldval > val) {
924+
if (unsigned_mult_overflows(factor, val) ||
925+
factor * val > max) {
930926
errno = ERANGE;
931927
return 0;
932928
}
929+
val *= factor;
933930
*ret = val;
934931
return 1;
935932
}

0 commit comments

Comments
 (0)