config: set errno in numeric git_parse_* functions
When we are parsing an integer or unsigned long, we use the strto*max functions, which properly set errno to ERANGE if we get a large value. However, we also do further range checks after applying our multiplication factor, but do not set ERANGE. This means that a caller cannot tell if an error was caused by ERANGE or if the input was simply not a valid number. This patch teaches git_parse_signed and git_parse_unsigned to set ERANGE for range errors, and EINVAL for other errors, so that the caller can reliably tell these cases apart. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Jeff King committed
Sep 8, 2013 at 04:36 UTC
33fdd77e2b8ece3490982f9a35c8669d16879ba8
1 file changed
+14
-4
config.c
+14
-4
@@ -480,16 +480,21 @@ static int git_parse_signed(const char *value, intmax_t *ret, intmax_t max)
480
val = strtoimax(value, &end, 0);
481
if (errno == ERANGE)
482
return 0;
483
- if (!parse_unit_factor(end, &factor))
483
+ if (!parse_unit_factor(end, &factor)) {
484
+ errno = EINVAL;
485
return 0;
486
+ }
487
uval = abs(val);
488
uval *= factor;
487
- if (uval > max || abs(val) > uval)
489
+ if (uval > max || abs(val) > uval) {
490
+ errno = ERANGE;
491
return 0;
492
+ }
493
val *= factor;
494
*ret = val;
495
return 1;
496
}
497
+ errno = EINVAL;
498
return 0;
499
}
500
@@ -505,13 +510,18 @@ int git_parse_unsigned(const char *value, uintmax_t *ret, uintmax_t max)
510
if (errno == ERANGE)
511
return 0;
512
oldval = val;
508
- if (!parse_unit_factor(end, &val))
513
+ if (!parse_unit_factor(end, &val)) {
514
+ errno = EINVAL;
515
return 0;
510
- if (val > max || oldval > val)
516
+ }
517
+ if (val > max || oldval > val) {
518
+ errno = ERANGE;
519
return 0;
520
+ }
521
*ret = val;
522
return 1;
523
}
524
+ errno = EINVAL;
525
return 0;
526
}
527