* 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. Fortunately this bug could not be triggered on GNU/Linux hosts, although it may be possible on platforms (if any) where struct ar_hdr has members so large that they can represent integers that do not fit int uintmax_t. --- src/arscan.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/src/arscan.c b/src/arscan.c index 00225410..8c33ed7c 100644 --- a/src/arscan.c +++ b/src/arscan.c @@ -395,16 +395,12 @@ parse_int (const char *ptr, const size_t len, const int base, uintmax_t max, while (ptr < ep && *ptr != ' ') { - uintmax_t nv; - - if (*ptr < '0' || *ptr > maxchar) - OSSS (fatal, NILF, - _("invalid %s for archive %s member %s"), type, archive, name); - 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) + || val > max) OSSS (fatal, NILF, _("invalid %s for archive %s member %s"), type, archive, name); - val = nv; ++ptr; } -- 2.43.0