diff options
-rw-r--r-- | ext/standard/php_random.h | 6 | ||||
-rw-r--r-- | ext/standard/random.c | 63 |
2 files changed, 45 insertions, 24 deletions
diff --git a/ext/standard/php_random.h b/ext/standard/php_random.h index c4034e7d8d..090e9d1dc4 100644 --- a/ext/standard/php_random.h +++ b/ext/standard/php_random.h @@ -34,7 +34,13 @@ typedef struct { #define php_random_bytes_throw(b, s) php_random_bytes((b), (s), 1) #define php_random_bytes_silent(b, s) php_random_bytes((b), (s), 0) +#define php_random_int_throw(min, max, result) \ + php_random_int((min), (max), (result), 1) +#define php_random_int_silent(min, max, result) \ + php_random_int((min), (max), (result), 0) + PHPAPI int php_random_bytes(void *bytes, size_t size, zend_bool should_throw); +PHPAPI int php_random_int(zend_long min, zend_long max, zend_long *result, zend_bool should_throw); #ifdef ZTS # define RANDOM_G(v) ZEND_TSRMG(random_globals_id, php_random_globals *, v) diff --git a/ext/standard/random.c b/ext/standard/random.c index c0e1abd2d2..1161d76fe2 100644 --- a/ext/standard/random.c +++ b/ext/standard/random.c @@ -81,7 +81,6 @@ PHP_MSHUTDOWN_FUNCTION(random) /* }}} */ /* {{{ */ - PHPAPI int php_random_bytes(void *bytes, size_t size, zend_bool should_throw) { #if PHP_WIN32 @@ -214,37 +213,27 @@ PHP_FUNCTION(random_bytes) } /* }}} */ -/* {{{ proto int random_int(int min, int max) -Return an arbitrary pseudo-random integer */ -PHP_FUNCTION(random_int) +/* {{{ */ +PHPAPI int php_random_int(zend_long min, zend_long max, zend_long *result, zend_bool should_throw) { - zend_long min; - zend_long max; zend_ulong umax; - zend_ulong result; - - if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "ll", &min, &max) == FAILURE) { - return; - } - - if (min > max) { - zend_throw_exception(zend_ce_error, "Minimum value must be less than or equal to the maximum value", 0); - return; - } + zend_ulong trial; if (min == max) { - RETURN_LONG(min); + *result = min; + return SUCCESS; } umax = max - min; - if (php_random_bytes_throw(&result, sizeof(result)) == FAILURE) { - return; + if (php_random_bytes(&trial, sizeof(trial), should_throw) == FAILURE) { + return FAILURE; } /* Special case where no modulus is required */ if (umax == ZEND_ULONG_MAX) { - RETURN_LONG((zend_long)result); + *result = (zend_long)trial; + return SUCCESS; } /* Increment the max so the range is inclusive of max */ @@ -256,14 +245,40 @@ PHP_FUNCTION(random_int) zend_ulong limit = ZEND_ULONG_MAX - (ZEND_ULONG_MAX % umax) - 1; /* Discard numbers over the limit to avoid modulo bias */ - while (result > limit) { - if (php_random_bytes_throw(&result, sizeof(result)) == FAILURE) { - return; + while (trial > limit) { + if (php_random_bytes(&trial, sizeof(trial), should_throw) == FAILURE) { + return FAILURE; } } } - RETURN_LONG((zend_long)((result % umax) + min)); + *result = (zend_long)((trial % umax) + min); + return SUCCESS; +} +/* }}} */ + +/* {{{ proto int random_int(int min, int max) +Return an arbitrary pseudo-random integer */ +PHP_FUNCTION(random_int) +{ + zend_long min; + zend_long max; + zend_long result; + + if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "ll", &min, &max) == FAILURE) { + return; + } + + if (min > max) { + zend_throw_exception(zend_ce_error, "Minimum value must be less than or equal to the maximum value", 0); + return; + } + + if (php_random_int_throw(min, max, &result) == FAILURE) { + return; + } + + RETURN_LONG(result); } /* }}} */ |