On 1/7/24 16:09, Paul Eggert wrote:
* src/arscan.c (parse_int): Use intprops.h macros rather than trying to detect integer overflow by hand, and doing it incorrectly. Here is an example of why the old code was incorrect. If val == 3689348814741910323, base == 10, *ptr == '0', UINTMAX_WIDTH == 64, then (val * base) + (*ptr - '0') yields 18446744073709551614, which is greater than val even though overflow has occurred.
- nv = (val * base) + (*ptr - '0'); - if (nv < val || nv > max) + if (*ptr < '0' || *ptr > maxchar + || INT_MULTIPLY_WRAPV (val, base, &val) + || INT_ADD_WRAPV (val, *ptr - '0', &val)
The patch is correct, but there is an opportunity to understand _why_ the old code is incorrect. The test "result < input", here (nv < val), is a correct test for overflow only for unsigned integer _addition_. The old code ignored the possibility of earlier overflow on the multiplication by 'base'. Also, using hexadecimal helps to understand this particular case. 3689348814741910323 is 0x3333333333333333. This is (0xffffffffffffffff / 5), so multiplying by 10 overflows 64-bit.