From 61ee4578f59e4478bf76fa584b199e1a22521cb0 Mon Sep 17 00:00:00 2001 From: Paul Eggert <eggert@cs.ucla.edu> Date: Sun, 7 Jan 2024 16:09:49 -0800 Subject: [PATCH] * src/arscan.c (parse_int): Fix integer overflow test Use intprops.h macros rather than trying to detect integer overflow by hand, and doing it incorrectly. Example of incorrect behavior: if val == 3689348814741910323, base == 10, UINTMAX_WIDTH == 64, and *ptr == '0' 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 eed90c80..f86e95f7 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) + 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); - nv = (val * base) + (*ptr - '0'); - if (nv < val || nv > max) - OSSS (fatal, NILF, - _("invalid %s for archive %s member %s"), type, archive, name); - val = nv; ++ptr; }