summaryrefslogtreecommitdiff
path: root/config.c
diff options
context:
space:
mode:
authorJeff King <peff@peff.net>2013-09-08 04:36:42 -0400
committerJunio C Hamano <gitster@pobox.com>2013-09-09 11:06:38 -0700
commit33fdd77e2b8ece3490982f9a35c8669d16879ba8 (patch)
tree4fdf8bc8a5dc3db299108feb14bf7aaf4c5b2071 /config.c
parent42d194e95870a9eeea192789226b7d51b1c90c96 (diff)
downloadgit-33fdd77e2b8ece3490982f9a35c8669d16879ba8.tar.gz
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>
Diffstat (limited to 'config.c')
-rw-r--r--config.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/config.c b/config.c
index d3f71b261e..9a42ad2ded 100644
--- a/config.c
+++ b/config.c
@@ -480,16 +480,21 @@ static int git_parse_signed(const char *value, intmax_t *ret, intmax_t max)
val = strtoimax(value, &end, 0);
if (errno == ERANGE)
return 0;
- if (!parse_unit_factor(end, &factor))
+ if (!parse_unit_factor(end, &factor)) {
+ errno = EINVAL;
return 0;
+ }
uval = abs(val);
uval *= factor;
- if (uval > max || abs(val) > uval)
+ if (uval > max || abs(val) > uval) {
+ errno = ERANGE;
return 0;
+ }
val *= factor;
*ret = val;
return 1;
}
+ errno = EINVAL;
return 0;
}
@@ -505,13 +510,18 @@ int git_parse_unsigned(const char *value, uintmax_t *ret, uintmax_t max)
if (errno == ERANGE)
return 0;
oldval = val;
- if (!parse_unit_factor(end, &val))
+ if (!parse_unit_factor(end, &val)) {
+ errno = EINVAL;
return 0;
- if (val > max || oldval > val)
+ }
+ if (val > max || oldval > val) {
+ errno = ERANGE;
return 0;
+ }
*ret = val;
return 1;
}
+ errno = EINVAL;
return 0;
}