Skip to content

Commit 97cb523

Browse files
committed
Merge branch 'rs/config-unit-parsing' into maint
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 e591501 + 39c575c commit 97cb523

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
@@ -834,22 +834,16 @@ static int git_parse_source(config_fn_t fn, void *data,
834834
return error_return;
835835
}
836836

837-
static int parse_unit_factor(const char *end, uintmax_t *val)
837+
static uintmax_t get_unit_factor(const char *end)
838838
{
839839
if (!*end)
840840
return 1;
841-
else if (!strcasecmp(end, "k")) {
842-
*val *= 1024;
843-
return 1;
844-
}
845-
else if (!strcasecmp(end, "m")) {
846-
*val *= 1024 * 1024;
847-
return 1;
848-
}
849-
else if (!strcasecmp(end, "g")) {
850-
*val *= 1024 * 1024 * 1024;
851-
return 1;
852-
}
841+
else if (!strcasecmp(end, "k"))
842+
return 1024;
843+
else if (!strcasecmp(end, "m"))
844+
return 1024 * 1024;
845+
else if (!strcasecmp(end, "g"))
846+
return 1024 * 1024 * 1024;
853847
return 0;
854848
}
855849

@@ -859,19 +853,20 @@ static int git_parse_signed(const char *value, intmax_t *ret, intmax_t max)
859853
char *end;
860854
intmax_t val;
861855
uintmax_t uval;
862-
uintmax_t factor = 1;
856+
uintmax_t factor;
863857

864858
errno = 0;
865859
val = strtoimax(value, &end, 0);
866860
if (errno == ERANGE)
867861
return 0;
868-
if (!parse_unit_factor(end, &factor)) {
862+
factor = get_unit_factor(end);
863+
if (!factor) {
869864
errno = EINVAL;
870865
return 0;
871866
}
872867
uval = val < 0 ? -val : val;
873-
uval *= factor;
874-
if (uval > max || (val < 0 ? -val : val) > uval) {
868+
if (unsigned_mult_overflows(factor, uval) ||
869+
factor * uval > max) {
875870
errno = ERANGE;
876871
return 0;
877872
}
@@ -888,21 +883,23 @@ static int git_parse_unsigned(const char *value, uintmax_t *ret, uintmax_t max)
888883
if (value && *value) {
889884
char *end;
890885
uintmax_t val;
891-
uintmax_t oldval;
886+
uintmax_t factor;
892887

893888
errno = 0;
894889
val = strtoumax(value, &end, 0);
895890
if (errno == ERANGE)
896891
return 0;
897-
oldval = val;
898-
if (!parse_unit_factor(end, &val)) {
892+
factor = get_unit_factor(end);
893+
if (!factor) {
899894
errno = EINVAL;
900895
return 0;
901896
}
902-
if (val > max || oldval > val) {
897+
if (unsigned_mult_overflows(factor, val) ||
898+
factor * val > max) {
903899
errno = ERANGE;
904900
return 0;
905901
}
902+
val *= factor;
906903
*ret = val;
907904
return 1;
908905
}

0 commit comments

Comments
 (0)