Skip to content

Commit 7192777

Browse files
peffgitster
authored andcommitted
config: factor out integer parsing from range checks
When we are parsing integers for config, we use an intmax_t (or uintmax_t) internally, and then check against the size of our result type at the end. We can parameterize the maximum representable value, which will let us re-use the parsing code for a variety of range checks. Unfortunately, we cannot combine the signed and unsigned parsing functions easily, as we have to rely on the signed and unsigned C types internally. Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 4d06473 commit 7192777

File tree

1 file changed

+22
-6
lines changed

1 file changed

+22
-6
lines changed

config.c

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,7 @@ static int parse_unit_factor(const char *end, uintmax_t *val)
468468
return 0;
469469
}
470470

471-
static int git_parse_long(const char *value, long *ret)
471+
static int git_parse_signed(const char *value, intmax_t *ret, intmax_t max)
472472
{
473473
if (value && *value) {
474474
char *end;
@@ -484,8 +484,7 @@ static int git_parse_long(const char *value, long *ret)
484484
return 0;
485485
uval = abs(val);
486486
uval *= factor;
487-
if ((uval > maximum_signed_value_of_type(long)) ||
488-
(abs(val) > uval))
487+
if (uval > max || abs(val) > uval)
489488
return 0;
490489
val *= factor;
491490
*ret = val;
@@ -494,7 +493,7 @@ static int git_parse_long(const char *value, long *ret)
494493
return 0;
495494
}
496495

497-
int git_parse_ulong(const char *value, unsigned long *ret)
496+
int git_parse_unsigned(const char *value, uintmax_t *ret, uintmax_t max)
498497
{
499498
if (value && *value) {
500499
char *end;
@@ -508,15 +507,32 @@ int git_parse_ulong(const char *value, unsigned long *ret)
508507
oldval = val;
509508
if (!parse_unit_factor(end, &val))
510509
return 0;
511-
if ((val > maximum_unsigned_value_of_type(long)) ||
512-
(oldval > val))
510+
if (val > max || oldval > val)
513511
return 0;
514512
*ret = val;
515513
return 1;
516514
}
517515
return 0;
518516
}
519517

518+
static int git_parse_long(const char *value, long *ret)
519+
{
520+
intmax_t tmp;
521+
if (!git_parse_signed(value, &tmp, maximum_signed_value_of_type(long)))
522+
return 0;
523+
*ret = tmp;
524+
return 1;
525+
}
526+
527+
int git_parse_ulong(const char *value, unsigned long *ret)
528+
{
529+
uintmax_t tmp;
530+
if (!git_parse_unsigned(value, &tmp, maximum_unsigned_value_of_type(long)))
531+
return 0;
532+
*ret = tmp;
533+
return 1;
534+
}
535+
520536
static void die_bad_config(const char *name)
521537
{
522538
if (cf && cf->name)

0 commit comments

Comments
 (0)