From: Bob Weinand Date: Tue, 8 Sep 2015 22:58:09 +0000 (+0200) Subject: Merged RFC Random Functions Throwing Exceptions in PHP 7 X-Git-Tag: php-7.1.0alpha1~1213 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c12917aa45639f7cb752645d2d1f37fd8b70c3e1;p=php Merged RFC Random Functions Throwing Exceptions in PHP 7 Squashes commits from PR #1397 commit cd5dcc8c9eb43603d908abcea69c9e18df0f2ed5 Author: SammyK Date: Tue Sep 8 13:53:42 2015 -0500 Add min max samezies commit b719499218a4e84efecd4dc1d4235d16142c9793 Author: SammyK Date: Wed Sep 2 07:00:25 2015 -0500 Make random_bytes() throw Error when $length <= 0 and random_int() throw Error when $min > $max commit 0cca557291c278716ec4b00b32fc2bdc1c1c8848 Author: SammyK Date: Wed Sep 2 06:55:59 2015 -0500 Make random_*() functions throw Error exception when random bytes cannot be obtained commit 998c7f1e209123605b41139e8d9093075ce16bd6 Author: SammyK Date: Wed Sep 2 06:41:20 2015 -0500 Make random_*() functions throw TypeError when zend_parse_parameters fails commit 99d305c18820ff55d82d952777cbcdf1cf0158be Author: SammyK Date: Mon Jul 6 19:50:47 2015 -0500 Make exceptions less specific commit b042dfab290713366741a663a420cf12bf802f39 Author: SammyK Date: Mon Jul 6 17:20:13 2015 -0500 Upgrade warnings to RuntimeExceptions --- diff --git a/NEWS b/NEWS index a790f82919..4e0d012121 100644 --- a/NEWS +++ b/NEWS @@ -30,6 +30,10 @@ PHP NEWS . Fixed bug #70449 (PHP won't compile on 10.4 and 10.5 because of missing constants). (Bob) +- Standard: + . Implemented the RFC `Random Functions Throwing Exceptions in PHP 7`. + (Sammy Kaye Powers, Anthony) + - Streams: . Fixed bug #70361 (HTTP stream wrapper doesn't close keep-alive connections). (Niklas Keller) diff --git a/ext/standard/random.c b/ext/standard/random.c index 9ae4e3c983..e2e48951cc 100644 --- a/ext/standard/random.c +++ b/ext/standard/random.c @@ -24,6 +24,7 @@ #include #include "php.h" +#include "zend_exceptions.h" #include "php_random.h" #if PHP_WIN32 @@ -79,7 +80,7 @@ static int php_random_bytes(void *bytes, size_t size) #if PHP_WIN32 /* Defer to CryptGenRandom on Windows */ if (php_win32_get_random_bytes(bytes, size) == FAILURE) { - php_error_docref(NULL, E_WARNING, "Could not gather sufficient random data"); + zend_throw_exception(zend_ce_exception, "Could not gather sufficient random data", 0); return FAILURE; } #elif HAVE_DECL_ARC4RANDOM_BUF @@ -95,7 +96,7 @@ static int php_random_bytes(void *bytes, size_t size) fd = open("/dev/urandom", O_RDONLY); #endif if (fd < 0) { - php_error_docref(NULL, E_WARNING, "Cannot open source device"); + zend_throw_exception(zend_ce_exception, "Cannot open source device", 0); return FAILURE; } @@ -111,7 +112,7 @@ static int php_random_bytes(void *bytes, size_t size) } if (read_bytes < size) { - php_error_docref(NULL, E_WARNING, "Could not gather sufficient random data"); + zend_throw_exception(zend_ce_exception, "Could not gather sufficient random data", 0); return FAILURE; } #endif @@ -127,20 +128,20 @@ PHP_FUNCTION(random_bytes) zend_long size; zend_string *bytes; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &size) == FAILURE) { + if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "l", &size) == FAILURE) { return; } if (size < 1) { - php_error_docref(NULL, E_WARNING, "Length must be greater than 0"); - RETURN_FALSE; + zend_throw_exception(zend_ce_error, "Length must be greater than 0", 0); + return; } bytes = zend_string_alloc(size, 0); if (php_random_bytes(ZSTR_VAL(bytes), size) == FAILURE) { zend_string_release(bytes); - RETURN_FALSE; + return; } ZSTR_VAL(bytes)[size] = '\0'; @@ -158,19 +159,23 @@ PHP_FUNCTION(random_int) zend_ulong umax; zend_ulong result; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "ll", &min, &max) == FAILURE) { + if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "ll", &min, &max) == FAILURE) { return; } - if (min >= max) { - php_error_docref(NULL, E_WARNING, "Minimum value must be less than the maximum value"); - RETURN_FALSE; + if (min > max) { + zend_throw_exception(zend_ce_error, "Minimum value must be less than or equal to the maximum value", 0); + return; + } + + if (min == max) { + RETURN_LONG(min); } umax = max - min; if (php_random_bytes(&result, sizeof(result)) == FAILURE) { - RETURN_FALSE; + return; } /* Special case where no modulus is required */ @@ -185,11 +190,11 @@ PHP_FUNCTION(random_int) if ((umax & (umax - 1)) != 0) { /* Ceiling under which ZEND_LONG_MAX % max == 0 */ 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(&result, sizeof(result)) == FAILURE) { - RETURN_FALSE; + return; } } } diff --git a/ext/standard/tests/random/random_bytes_error.phpt b/ext/standard/tests/random/random_bytes_error.phpt index 466a3ac3bf..c1607c01ff 100644 --- a/ext/standard/tests/random/random_bytes_error.phpt +++ b/ext/standard/tests/random/random_bytes_error.phpt @@ -4,14 +4,19 @@ Test error operation of random_bytes() getMessage().PHP_EOL; +} -var_dump(random_bytes(-1)); +try { + $bytes = random_bytes(0); +} catch (Error $e) { + echo $e->getMessage().PHP_EOL; +} ?> ---EXPECTF-- -Warning: random_bytes() expects exactly 1 parameter, 0 given in %s on line %d -NULL - -Warning: random_bytes(): Length must be greater than 0 in %s on line %d -bool(false) +--EXPECT-- +random_bytes() expects exactly 1 parameter, 0 given +Length must be greater than 0 diff --git a/ext/standard/tests/random/random_int.phpt b/ext/standard/tests/random/random_int.phpt index 0c3081452c..768bc4f97d 100644 --- a/ext/standard/tests/random/random_int.phpt +++ b/ext/standard/tests/random/random_int.phpt @@ -11,8 +11,11 @@ var_dump($x >= 10 && $x <= 100); var_dump(random_int(-1000, -1) < 0); +var_dump(random_int(42,42)); + ?> --EXPECT-- bool(true) bool(true) bool(true) +int(42) diff --git a/ext/standard/tests/random/random_int_error.phpt b/ext/standard/tests/random/random_int_error.phpt index 5f7a69b215..9b98bdd7c0 100644 --- a/ext/standard/tests/random/random_int_error.phpt +++ b/ext/standard/tests/random/random_int_error.phpt @@ -4,19 +4,26 @@ Test error operation of random_int() getMessage().PHP_EOL; +} -var_dump(random_int(10)); +try { + $randomInt = random_int(42); +} catch (TypeError $e) { + echo $e->getMessage().PHP_EOL; +} -var_dump(random_int(10, 0)); +try { + $randomInt = random_int(42,0); +} catch (Error $e) { + echo $e->getMessage().PHP_EOL; +} ?> ---EXPECTF-- -Warning: random_int() expects exactly 2 parameters, 0 given in %s on line %d -NULL - -Warning: random_int() expects exactly 2 parameters, 1 given in %s on line %d -NULL - -Warning: random_int(): Minimum value must be less than the maximum value in %s on line %d -bool(false) +--EXPECT-- +random_int() expects exactly 2 parameters, 0 given +random_int() expects exactly 2 parameters, 1 given +Minimum value must be less than or equal to the maximum value