зеркало из https://github.com/microsoft/git.git
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 <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Родитель
4d06473928
Коммит
7192777d22
28
config.c
28
config.c
|
@ -468,7 +468,7 @@ static int parse_unit_factor(const char *end, uintmax_t *val)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int git_parse_long(const char *value, long *ret)
|
||||
static int git_parse_signed(const char *value, intmax_t *ret, intmax_t max)
|
||||
{
|
||||
if (value && *value) {
|
||||
char *end;
|
||||
|
@ -484,8 +484,7 @@ static int git_parse_long(const char *value, long *ret)
|
|||
return 0;
|
||||
uval = abs(val);
|
||||
uval *= factor;
|
||||
if ((uval > maximum_signed_value_of_type(long)) ||
|
||||
(abs(val) > uval))
|
||||
if (uval > max || abs(val) > uval)
|
||||
return 0;
|
||||
val *= factor;
|
||||
*ret = val;
|
||||
|
@ -494,7 +493,7 @@ static int git_parse_long(const char *value, long *ret)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int git_parse_ulong(const char *value, unsigned long *ret)
|
||||
int git_parse_unsigned(const char *value, uintmax_t *ret, uintmax_t max)
|
||||
{
|
||||
if (value && *value) {
|
||||
char *end;
|
||||
|
@ -508,8 +507,7 @@ int git_parse_ulong(const char *value, unsigned long *ret)
|
|||
oldval = val;
|
||||
if (!parse_unit_factor(end, &val))
|
||||
return 0;
|
||||
if ((val > maximum_unsigned_value_of_type(long)) ||
|
||||
(oldval > val))
|
||||
if (val > max || oldval > val)
|
||||
return 0;
|
||||
*ret = val;
|
||||
return 1;
|
||||
|
@ -517,6 +515,24 @@ int git_parse_ulong(const char *value, unsigned long *ret)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int git_parse_long(const char *value, long *ret)
|
||||
{
|
||||
intmax_t tmp;
|
||||
if (!git_parse_signed(value, &tmp, maximum_signed_value_of_type(long)))
|
||||
return 0;
|
||||
*ret = tmp;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int git_parse_ulong(const char *value, unsigned long *ret)
|
||||
{
|
||||
uintmax_t tmp;
|
||||
if (!git_parse_unsigned(value, &tmp, maximum_unsigned_value_of_type(long)))
|
||||
return 0;
|
||||
*ret = tmp;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void die_bad_config(const char *name)
|
||||
{
|
||||
if (cf && cf->name)
|
||||
|
|
Загрузка…
Ссылка в новой задаче