summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2020-09-15 09:00:45 +0000
committervlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2020-09-15 09:00:45 +0000
commit01f58989238361e3622483c0f8f4ba58c924df3b (patch)
tree33b34439b7874c36fb31ca6c36d66a2819641d4d
parentca334cbd97562db39c4942dd96591c0edab4766a (diff)
downloadmpfr-01f58989238361e3622483c0f8f4ba58c924df3b.tar.gz
[src/mpfr-mini-gmp.c] Fixed bug in gmp_urandomb_ui when the parameter n
is equal to the width of unsigned long. Note: This case occurs in function random_deviate_generate() from src/random_deviate.c with a 32-bit ABI (thus 32-bit unsigned long) since n = W, which is defined as 32. (merged changeset r14117 from the trunk) git-svn-id: https://scm.gforge.inria.fr/anonscm/svn/mpfr/branches/4.1@14119 280ebfd0-de03-0410-8827-d642c229c3f4
-rw-r--r--src/mpfr-mini-gmp.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/src/mpfr-mini-gmp.c b/src/mpfr-mini-gmp.c
index 8e0533271..c8409674f 100644
--- a/src/mpfr-mini-gmp.c
+++ b/src/mpfr-mini-gmp.c
@@ -153,7 +153,9 @@ unsigned long
gmp_urandomb_ui (gmp_randstate_t state, unsigned long n)
{
#ifdef MPFR_LONG_WITHIN_LIMB
- return random_limb () % (1UL << n);
+ /* Since n may be equal to the width of unsigned long,
+ we must not shift 1UL by n as this may be UB. */
+ return n == 0 ? 0 : random_limb () & (((1UL << (n - 1)) << 1) - 1);
#else
unsigned long res = 0;
int m = n; /* remaining bits to generate */
@@ -163,8 +165,8 @@ gmp_urandomb_ui (gmp_randstate_t state, unsigned long n)
res = (res << GMP_NUMB_BITS) | (unsigned long) random_limb ();
m -= GMP_NUMB_BITS;
}
- /* now m < GMP_NUMB_BITS */
- if (m) /* generate m extra bits */
+ MPFR_ASSERTD (m < GMP_NUMB_BITS); /* thus m < width(unsigned long) */
+ if (m != 0) /* generate m extra bits */
res = (res << m) | (unsigned long) (random_limb () % (1UL << m));
return res;
#endif