From 374f5fdcc1cca96e2ae89168eba7d9f25c4d48c9 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sat, 24 May 2025 11:57:05 -0700 Subject: [PATCH] factor: check unsigned char counts MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit * src/factor.c (MAX_NFACTS): Allow word size of 128 bits, even if this is only theoretical now. Check that struct factors’s unsigned char counts won’t overflow. --- src/factor.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/factor.c b/src/factor.c index 54eb9aa92c..2d91e9e4fc 100644 --- a/src/factor.c +++ b/src/factor.c @@ -200,8 +200,16 @@ typedef uint64_t UDItype; #endif -/* 2*3*5*7*11...*101 is 128 bits, and has 26 prime factors */ -#define MAX_NFACTS 26 +/* 2*3*5*7*11...*101 fits in 128 bits, and has 26 prime factors. + This code can be extended in the future as needed; show as an example + 2*3*5*7*11...*193 which fits in 257 bits, and has 44 prime factors. */ +#if 2 * W_TYPE_SIZE <= 128 +# define MAX_NFACTS 26 +#elif 2 * W_TYPE_SIZE <= 257 +# define MAX_NFACTS 44 +#else +# error "configuration has a wide word; please update MAX_NFACTS definition" +#endif enum { @@ -266,6 +274,13 @@ static mp_limb_t const BIG_POWER_OF_10 = enum { LOG_BIG_POWER_OF_10 = 38 }; #endif +/* Check that struct factors can use unsigned char to record a uuint's + prime factor's multiplicity, which is at most 2 * W_TYPE_SIZE - 1. */ +static_assert (2 * W_TYPE_SIZE - 1 <= UCHAR_MAX); + +/* Likewise for recording the number of prime factors. */ +static_assert (MAX_NFACTS <= UCHAR_MAX); + struct factors { uuint plarge; /* Can have a single large factor */ -- 2.47.3