diff --git a/NEWS b/NEWS index 3eb9779fde9..66896a7328f 100644 --- a/NEWS +++ b/NEWS @@ -55,6 +55,8 @@ PHP NEWS . Fixed floating point exception bug with gmp_pow when using large exposant values. (David Carlier). . Fixed bug GH-16411 (gmp_export() can cause overflow). (cmb) + . Fixed bug GH-16501 (gmp_random_bits() can cause overflow). + (David Carlier) - MBstring: . Fixed bug GH-16361 (mb_substr overflow on start/length arguments). diff --git a/ext/gmp/gmp.c b/ext/gmp/gmp.c index f3cb4a6ce10..14ce57aa49b 100644 --- a/ext/gmp/gmp.c +++ b/ext/gmp/gmp.c @@ -1821,15 +1821,21 @@ ZEND_FUNCTION(gmp_random_bits) RETURN_THROWS(); } - if (bits <= 0) { - zend_argument_value_error(1, "must be greater than or equal to 1"); +#if SIZEOF_SIZE_T == 4 + const zend_long maxbits = ULONG_MAX / GMP_NUMB_BITS; +#else + const zend_long maxbits = INT_MAX; +#endif + + if (bits <= 0 || bits > maxbits) { + zend_argument_value_error(1, "must be between 1 and " ZEND_LONG_FMT, maxbits); RETURN_THROWS(); } INIT_GMP_RETVAL(gmpnum_result); gmp_init_random(); - mpz_urandomb(gmpnum_result, GMPG(rand_state), bits); + mpz_urandomb(gmpnum_result, GMPG(rand_state), (mp_bitcnt_t)bits); } /* }}} */ diff --git a/ext/gmp/tests/gh16501.phpt b/ext/gmp/tests/gh16501.phpt new file mode 100644 index 00000000000..325be85d191 --- /dev/null +++ b/ext/gmp/tests/gh16501.phpt @@ -0,0 +1,14 @@ +--TEST-- +GH-16501 (gmp_random_bits overflow) +--EXTENSIONS-- +gmp +--FILE-- +getMessage(); +} +?> +--EXPECTF-- +gmp_random_bits(): Argument #1 ($bits) must be between 1 and %d diff --git a/ext/gmp/tests/gmp_random_bits.phpt b/ext/gmp/tests/gmp_random_bits.phpt index 3dbfc097d28..4e7f3379838 100644 --- a/ext/gmp/tests/gmp_random_bits.phpt +++ b/ext/gmp/tests/gmp_random_bits.phpt @@ -40,7 +40,7 @@ while (1) { echo "Done\n"; ?> ---EXPECT-- -gmp_random_bits(): Argument #1 ($bits) must be greater than or equal to 1 -gmp_random_bits(): Argument #1 ($bits) must be greater than or equal to 1 +--EXPECTF-- +gmp_random_bits(): Argument #1 ($bits) must be between 1 and %d +gmp_random_bits(): Argument #1 ($bits) must be between 1 and %d Done