From c7aa6eddf3c45e61e225f0c8ea40e8a185be3563 Mon Sep 17 00:00:00 2001 From: Jelte Fennema Date: Wed, 11 Mar 2020 23:03:02 +0100 Subject: [PATCH] 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. --- src/backend/distributed/utils/citus_safe_lib.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/backend/distributed/utils/citus_safe_lib.c b/src/backend/distributed/utils/citus_safe_lib.c index 56ea7cdc7..3a3c06b4a 100644 --- a/src/backend/distributed/utils/citus_safe_lib.c +++ b/src/backend/distributed/utils/citus_safe_lib.c @@ -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))); }