From: Leigh Date: Sat, 16 Jul 2016 16:50:20 +0000 (+0000) Subject: Fix legacy mode RAND_RANGE and 32/64-bit consistency X-Git-Tag: php-7.1.0beta1~43^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=027375d4c3a59b0f174b1beb70ba8f60efef6905;p=php Fix legacy mode RAND_RANGE and 32/64-bit consistency --- diff --git a/ext/standard/mt_rand.c b/ext/standard/mt_rand.c index fa7c004b65..bf9ce66f65 100644 --- a/ext/standard/mt_rand.c +++ b/ext/standard/mt_rand.c @@ -217,11 +217,10 @@ PHPAPI zend_long php_mt_rand_range(zend_long min, zend_long max) zend_ulong limit; zend_ulong result; -#if ZEND_ULONG_MAX > UINT32_MAX - result = ((zend_ulong)php_mt_rand() << 32) | php_mt_rand(); -#else result = php_mt_rand(); -#endif + if (umax > UINT32_MAX) { + result = (result << 32) | php_mt_rand(); + } /* Special case where no modulus is required */ if (UNEXPECTED(umax == ZEND_ULONG_MAX)) { @@ -238,11 +237,7 @@ PHPAPI zend_long php_mt_rand_range(zend_long min, zend_long max) /* Discard numbers over the limit to avoid modulo bias */ while (UNEXPECTED(result > limit)) { -#if ZEND_ULONG_MAX > UINT32_MAX result = (result << 32) | php_mt_rand(); -#else - result = php_mt_rand(); -#endif } } @@ -256,6 +251,7 @@ PHP_FUNCTION(mt_rand) { zend_long min; zend_long max; + zend_long n; int argc = ZEND_NUM_ARGS(); if (argc == 0) { @@ -272,7 +268,15 @@ PHP_FUNCTION(mt_rand) RETURN_FALSE; } - RETURN_LONG(php_mt_rand_range(min, max)); + if (BG(mt_rand_mode) == MT_RAND_MT19937) { + RETURN_LONG(php_mt_rand_range(min, max)); + } + + /* Legacy mode deliberately not inside php_mt_rand_range() + * to prevent other functions being affected */ + n = (zend_long)php_mt_rand() >> 1; + RAND_RANGE_BADSCALING(n, min, max, PHP_MT_RAND_MAX); + RETURN_LONG(n); } /* }}} */ diff --git a/ext/standard/php_rand.h b/ext/standard/php_rand.h index 76a368484d..506e4976a6 100644 --- a/ext/standard/php_rand.h +++ b/ext/standard/php_rand.h @@ -60,6 +60,9 @@ * * -RL */ +#define RAND_RANGE_BADSCALING(__n, __min, __max, __tmax) \ + (__n) = (__min) + (zend_long) ((double) ( (double) (__max) - (__min) + 1.0) * ((__n) / ((__tmax) + 1.0))) + #define RAND_RANGE(__n, __min, __max, __tmax) \ (__n) = php_mt_rand_range((__min), (__max))