Hi, I recently reviewed a patch [1] that switches strtoint() to strtoi64() to handle an int32 overflow problem. I initially thought we could keep using strtoint(), but then realized that its current return value cannot reliably indicate the direction of overflow, which the caller needs to clamp the value correctly.
Looking at the current code:
```
/*
* strtoint --- just like strtol, but returns int not long
*/
int
strtoint(const char *pg_restrict str, char **pg_restrict endptr, int base)
{
long val;
val = strtol(str, endptr, base);
if (val != (int) val)
errno = ERANGE;
return (int) val;
}
```
When overflow occurs, it returns “(int) val”, and when the value is outside the
range of int, the cast produces an implementation-defined result, which cannot
reliably indicate the direction of overflow. See the C11 draft [2], section
6.3.1.3, paragraph 3.
The header comment says “just like strtol”, but strtol() returns LONG_MAX or
LONG_MIN when overflow happens. See [3]:
```
If the correct value is outside the range of representable values,
{LONG_MIN}, {LONG_MAX}, {LLONG_MIN}, or {LLONG_MAX} shall be
returned (according to the sign of the value), and errno set to
[ERANGE].
```
So, the current implementation doesn’t fully match the intention described in
the header comment.
Attached is a simple fix to change strtoint() to return INT_MAX or INT_MIN upon
overflow, which makes its behavior consistent with strtol(). I have run “make
check-world”, and all tests passed.
If this patch is accepted, I will go back to patch [1] and comment my original
thoughts on that patch.
[1] https://postgr.es/m/[email protected]
[2] https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf#page=69
[3] https://man7.org/linux/man-pages/man3/strtol.3p.html
Best regards,
--
Chao Li (Evan)
HighGo Software Co., Ltd.
https://www.highgo.com/
v1-0001-Return-INT_MAX-or-INT_MIN-from-strtoint-on-overfl.patch
Description: Binary data
