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>
This commit is contained in:
Jeff King 2013-09-08 04:36:42 -04:00 коммит произвёл Junio C Hamano
Родитель 42d194e958
Коммит 33fdd77e2b
1 изменённых файлов: 14 добавлений и 4 удалений

Просмотреть файл

@ -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;
}