diff options
author | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2020-09-15 09:00:45 +0000 |
---|---|---|
committer | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2020-09-15 09:00:45 +0000 |
commit | 01f58989238361e3622483c0f8f4ba58c924df3b (patch) | |
tree | 33b34439b7874c36fb31ca6c36d66a2819641d4d | |
parent | ca334cbd97562db39c4942dd96591c0edab4766a (diff) | |
download | mpfr-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.c | 8 |
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 |