]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
factor: check unsigned char counts
authorPaul Eggert <eggert@cs.ucla.edu>
Sat, 24 May 2025 18:57:05 +0000 (11:57 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Thu, 10 Jul 2025 00:12:39 +0000 (17:12 -0700)
* 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

index 54eb9aa92cac04b5dca40265fdd8800717cff992..2d91e9e4fca2d918d6b461b8e00b3cec1abe725d 100644 (file)
@@ -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 */