diff --git a/NEWS b/NEWS index 7fb9b27dc7688..32062ccc298ec 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,8 @@ PHP NEWS - Random: . Fixed bug GH-9235 (non-existant $sequence parameter in stub for PcgOneseq128XslRr64::__construct()). (timwolla) + . Fixed bug GH-9190, GH-9191 (undefined behavior for MT_RAND_PHP when + handling large ranges). (timwolla) . Removed redundant RuntimeExceptions from Randomizer methods. The exceptions thrown by the engines will be exposed directly. (timwolla) . Added extension specific Exceptions/Errors (RandomException, RandomError, diff --git a/ext/random/engine_mt19937.c b/ext/random/engine_mt19937.c index d7d355b90d6b4..266ec5ea11c24 100644 --- a/ext/random/engine_mt19937.c +++ b/ext/random/engine_mt19937.c @@ -168,11 +168,17 @@ static zend_long range(php_random_status *status, zend_long min, zend_long max) return php_random_range(&php_random_algo_mt19937, status, min, max); } - uint64_t r = php_random_algo_mt19937.generate(status) >> 1; /* Legacy mode deliberately not inside php_mt_rand_range() * to prevent other functions being affected */ - RAND_RANGE_BADSCALING(r, min, max, PHP_MT_RAND_MAX); - return (zend_long) r; + + uint64_t r = php_random_algo_mt19937.generate(status) >> 1; + + /* This is an inlined version of the RAND_RANGE_BADSCALING macro that does not invoke UB when encountering + * (max - min) > ZEND_LONG_MAX. + */ + zend_ulong offset = (double) ( (double) max - min + 1.0) * (r / (PHP_MT_RAND_MAX + 1.0)); + + return (zend_long) (offset + min); } static bool serialize(php_random_status *status, HashTable *data)