diff options
author | Leigh <leigh@php.net> | 2016-08-10 23:32:32 +0100 |
---|---|---|
committer | Leigh <leigh@php.net> | 2016-08-10 23:32:32 +0100 |
commit | 9a9004318fa3a5b2c2c3c4a4fafed9ad4767df4a (patch) | |
tree | 23a54936a7006cf9c96970d168f1597923621890 | |
parent | 24fdffdacbfeaa20e8f08d44c7c61e3fb7ba9ac5 (diff) | |
download | php-git-9a9004318fa3a5b2c2c3c4a4fafed9ad4767df4a.tar.gz |
Preserve BC for rand() AND mt_rand() where min > max
-rw-r--r-- | ext/standard/basic_functions.c | 2 | ||||
-rw-r--r-- | ext/standard/mt_rand.c | 32 | ||||
-rw-r--r-- | ext/standard/php_math.h | 1 | ||||
-rw-r--r-- | ext/standard/php_mt_rand.h | 1 | ||||
-rw-r--r-- | ext/standard/rand.c | 24 |
5 files changed, 48 insertions, 12 deletions
diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index ef03db14db..88e628ae05 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -2851,7 +2851,7 @@ const zend_function_entry basic_functions[] = { /* {{{ */ PHP_FE(proc_nice, arginfo_proc_nice) #endif - PHP_FALIAS(rand, mt_rand, arginfo_mt_rand) + PHP_FE(rand, arginfo_mt_rand) PHP_FALIAS(srand, mt_srand, arginfo_mt_srand) PHP_FALIAS(getrandmax, mt_getrandmax, arginfo_mt_getrandmax) PHP_FE(mt_rand, arginfo_mt_rand) diff --git a/ext/standard/mt_rand.c b/ext/standard/mt_rand.c index f2866c5af2..dde9a77134 100644 --- a/ext/standard/mt_rand.c +++ b/ext/standard/mt_rand.c @@ -256,13 +256,31 @@ PHPAPI zend_long php_mt_rand_range(zend_long min, zend_long max) } /* }}} */ +/* {{{ php_mt_rand_common + * rand() allows min > max, mt_rand does not */ +PHPAPI zend_long php_mt_rand_common(zend_long min, zend_long max) +{ + zend_long n; + + if (BG(mt_rand_mode) == MT_RAND_MT19937) { + return 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 n; +} +/* }}} */ + /* {{{ proto int mt_rand([int min, int max]) Returns a random number from Mersenne Twister */ PHP_FUNCTION(mt_rand) { zend_long min; zend_long max; - zend_long n; int argc = ZEND_NUM_ARGS(); if (argc == 0) { @@ -276,18 +294,10 @@ PHP_FUNCTION(mt_rand) if (UNEXPECTED(max < min)) { php_error_docref(NULL, E_WARNING, "max(" ZEND_LONG_FMT ") is smaller than min(" ZEND_LONG_FMT ")", max, min); - max ^= min ^= max ^= min; + RETURN_FALSE; } - 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); + RETURN_LONG(php_mt_rand_common(min, max)); } /* }}} */ diff --git a/ext/standard/php_math.h b/ext/standard/php_math.h index 9798db8422..bc5b5125ee 100644 --- a/ext/standard/php_math.h +++ b/ext/standard/php_math.h @@ -45,6 +45,7 @@ PHP_FUNCTION(is_infinite); PHP_FUNCTION(is_nan); PHP_FUNCTION(pow); PHP_FUNCTION(sqrt); +PHP_FUNCTION(rand); PHP_FUNCTION(mt_srand); PHP_FUNCTION(mt_rand); PHP_FUNCTION(mt_getrandmax); diff --git a/ext/standard/php_mt_rand.h b/ext/standard/php_mt_rand.h index bf0f6c20a1..e33d558591 100644 --- a/ext/standard/php_mt_rand.h +++ b/ext/standard/php_mt_rand.h @@ -36,6 +36,7 @@ PHPAPI void php_mt_srand(uint32_t seed); PHPAPI uint32_t php_mt_rand(void); PHPAPI zend_long php_mt_rand_range(zend_long min, zend_long max); +PHPAPI zend_long php_mt_rand_common(zend_long min, zend_long max); PHP_MINIT_FUNCTION(mt_rand); diff --git a/ext/standard/rand.c b/ext/standard/rand.c index 2720f55661..e97e0b46f0 100644 --- a/ext/standard/rand.c +++ b/ext/standard/rand.c @@ -45,6 +45,30 @@ PHPAPI zend_long php_rand(void) } /* }}} */ +/* {{{ proto int mt_rand([int min, int max]) + Returns a random number from Mersenne Twister */ +PHP_FUNCTION(rand) +{ + zend_long min; + zend_long max; + int argc = ZEND_NUM_ARGS(); + + if (argc == 0) { + RETURN_LONG(php_mt_rand() >> 1); + } + + if (zend_parse_parameters(argc, "ll", &min, &max) == FAILURE) { + return; + } + + if (max < min) { + RETURN_LONG(php_mt_rand_common(max, min)); + } + + RETURN_LONG(php_mt_rand_common(min, max)); +} +/* }}} */ + /* * Local variables: * tab-width: 4 |