Fix some bugs in string to int functions (#3602)

This fixes 3 bugs:
1. `strtoul` never underflows, so that branch was useless
2. `strtoul` has ULONG_MAX instead of LONG_MAX when it overflows
3. `long` and `unsigned long` are not necessarily 64bit, they can be
    either more or less. So now `strtoll` and `strtoull` are used 
    and 64 bit bounds are checked.
pull/3611/head
Jelte Fennema 2020-03-11 23:03:02 +01:00 committed by GitHub
parent c4cc26ed37
commit c7aa6eddf3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 5 additions and 9 deletions

View File

@ -83,17 +83,17 @@ SafeStringToInt64(const char *str)
{
char *endptr;
errno = 0;
int64 number = strtol(str, &endptr, 10);
long long number = strtoll(str, &endptr, 10);
if (str == endptr)
{
ereport(ERROR, (errmsg("Error parsing %s as int64, no digits found\n", str)));
}
else if (errno == ERANGE && number == LONG_MIN)
else if ((errno == ERANGE && number == LLONG_MIN) || number < INT64_MIN)
{
ereport(ERROR, (errmsg("Error parsing %s as int64, underflow occured\n", str)));
}
else if (errno == ERANGE && number == LONG_MAX)
else if ((errno == ERANGE && number == LLONG_MAX) || number > INT64_MAX)
{
ereport(ERROR, (errmsg("Error parsing %s as int64, overflow occured\n", str)));
}
@ -130,17 +130,13 @@ SafeStringToUint64(const char *str)
{
char *endptr;
errno = 0;
uint64 number = strtoul(str, &endptr, 10);
unsigned long long number = strtoull(str, &endptr, 10);
if (str == endptr)
{
ereport(ERROR, (errmsg("Error parsing %s as uint64, no digits found\n", str)));
}
else if (errno == ERANGE && number == LONG_MIN)
{
ereport(ERROR, (errmsg("Error parsing %s as uint64, underflow occured\n", str)));
}
else if (errno == ERANGE && number == LONG_MAX)
else if ((errno == ERANGE && number == ULLONG_MAX) || number > UINT64_MAX)
{
ereport(ERROR, (errmsg("Error parsing %s as uint64, overflow occured\n", str)));
}