diff options
author | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2020-09-15 00:04:22 +0000 |
---|---|---|
committer | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2020-09-15 00:04:22 +0000 |
commit | 6df21b702e4bb1745202401a15fc0481ae2f7986 (patch) | |
tree | 38ccc924aae9858d273ddbe6bfc368107fee6f86 /src/mpfr-mini-gmp.c | |
parent | dd58c63a55fa3d44db84249003a4348700b53ddf (diff) | |
download | mpfr-6df21b702e4bb1745202401a15fc0481ae2f7986.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.
git-svn-id: https://scm.gforge.inria.fr/anonscm/svn/mpfr/trunk@14117 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'src/mpfr-mini-gmp.c')
-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 |