Skip to content

Commit c12917a

Browse files
committed
Merged RFC Random Functions Throwing Exceptions in PHP 7
Squashes commits from PR #1397 commit cd5dcc8c9eb43603d908abcea69c9e18df0f2ed5 Author: SammyK <[email protected]> Date: Tue Sep 8 13:53:42 2015 -0500 Add min max samezies commit b719499218a4e84efecd4dc1d4235d16142c9793 Author: SammyK <[email protected]> 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 <[email protected]> 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 <[email protected]> Date: Wed Sep 2 06:41:20 2015 -0500 Make random_*() functions throw TypeError when zend_parse_parameters fails commit 99d305c18820ff55d82d952777cbcdf1cf0158be Author: SammyK <[email protected]> Date: Mon Jul 6 19:50:47 2015 -0500 Make exceptions less specific commit b042dfab290713366741a663a420cf12bf802f39 Author: SammyK <[email protected]> Date: Mon Jul 6 17:20:13 2015 -0500 Upgrade warnings to RuntimeExceptions
1 parent aa3fd8c commit c12917a

File tree

5 files changed

+58
-34
lines changed

5 files changed

+58
-34
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ PHP NEWS
3030
. Fixed bug #70449 (PHP won't compile on 10.4 and 10.5 because of missing
3131
constants). (Bob)
3232

33+
- Standard:
34+
. Implemented the RFC `Random Functions Throwing Exceptions in PHP 7`.
35+
(Sammy Kaye Powers, Anthony)
36+
3337
- Streams:
3438
. Fixed bug #70361 (HTTP stream wrapper doesn't close keep-alive connections).
3539
(Niklas Keller)

ext/standard/random.c

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <math.h>
2525

2626
#include "php.h"
27+
#include "zend_exceptions.h"
2728
#include "php_random.h"
2829

2930
#if PHP_WIN32
@@ -79,7 +80,7 @@ static int php_random_bytes(void *bytes, size_t size)
7980
#if PHP_WIN32
8081
/* Defer to CryptGenRandom on Windows */
8182
if (php_win32_get_random_bytes(bytes, size) == FAILURE) {
82-
php_error_docref(NULL, E_WARNING, "Could not gather sufficient random data");
83+
zend_throw_exception(zend_ce_exception, "Could not gather sufficient random data", 0);
8384
return FAILURE;
8485
}
8586
#elif HAVE_DECL_ARC4RANDOM_BUF
@@ -95,7 +96,7 @@ static int php_random_bytes(void *bytes, size_t size)
9596
fd = open("/dev/urandom", O_RDONLY);
9697
#endif
9798
if (fd < 0) {
98-
php_error_docref(NULL, E_WARNING, "Cannot open source device");
99+
zend_throw_exception(zend_ce_exception, "Cannot open source device", 0);
99100
return FAILURE;
100101
}
101102

@@ -111,7 +112,7 @@ static int php_random_bytes(void *bytes, size_t size)
111112
}
112113

113114
if (read_bytes < size) {
114-
php_error_docref(NULL, E_WARNING, "Could not gather sufficient random data");
115+
zend_throw_exception(zend_ce_exception, "Could not gather sufficient random data", 0);
115116
return FAILURE;
116117
}
117118
#endif
@@ -127,20 +128,20 @@ PHP_FUNCTION(random_bytes)
127128
zend_long size;
128129
zend_string *bytes;
129130

130-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &size) == FAILURE) {
131+
if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "l", &size) == FAILURE) {
131132
return;
132133
}
133134

134135
if (size < 1) {
135-
php_error_docref(NULL, E_WARNING, "Length must be greater than 0");
136-
RETURN_FALSE;
136+
zend_throw_exception(zend_ce_error, "Length must be greater than 0", 0);
137+
return;
137138
}
138139

139140
bytes = zend_string_alloc(size, 0);
140141

141142
if (php_random_bytes(ZSTR_VAL(bytes), size) == FAILURE) {
142143
zend_string_release(bytes);
143-
RETURN_FALSE;
144+
return;
144145
}
145146

146147
ZSTR_VAL(bytes)[size] = '\0';
@@ -158,19 +159,23 @@ PHP_FUNCTION(random_int)
158159
zend_ulong umax;
159160
zend_ulong result;
160161

161-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "ll", &min, &max) == FAILURE) {
162+
if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "ll", &min, &max) == FAILURE) {
162163
return;
163164
}
164165

165-
if (min >= max) {
166-
php_error_docref(NULL, E_WARNING, "Minimum value must be less than the maximum value");
167-
RETURN_FALSE;
166+
if (min > max) {
167+
zend_throw_exception(zend_ce_error, "Minimum value must be less than or equal to the maximum value", 0);
168+
return;
169+
}
170+
171+
if (min == max) {
172+
RETURN_LONG(min);
168173
}
169174

170175
umax = max - min;
171176

172177
if (php_random_bytes(&result, sizeof(result)) == FAILURE) {
173-
RETURN_FALSE;
178+
return;
174179
}
175180

176181
/* Special case where no modulus is required */
@@ -185,11 +190,11 @@ PHP_FUNCTION(random_int)
185190
if ((umax & (umax - 1)) != 0) {
186191
/* Ceiling under which ZEND_LONG_MAX % max == 0 */
187192
zend_ulong limit = ZEND_ULONG_MAX - (ZEND_ULONG_MAX % umax) - 1;
188-
193+
189194
/* Discard numbers over the limit to avoid modulo bias */
190195
while (result > limit) {
191196
if (php_random_bytes(&result, sizeof(result)) == FAILURE) {
192-
RETURN_FALSE;
197+
return;
193198
}
194199
}
195200
}

ext/standard/tests/random/random_bytes_error.phpt

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,19 @@ Test error operation of random_bytes()
44
<?php
55
//-=-=-=-
66

7-
var_dump(random_bytes());
7+
try {
8+
$bytes = random_bytes();
9+
} catch (TypeError $e) {
10+
echo $e->getMessage().PHP_EOL;
11+
}
812

9-
var_dump(random_bytes(-1));
13+
try {
14+
$bytes = random_bytes(0);
15+
} catch (Error $e) {
16+
echo $e->getMessage().PHP_EOL;
17+
}
1018

1119
?>
12-
--EXPECTF--
13-
Warning: random_bytes() expects exactly 1 parameter, 0 given in %s on line %d
14-
NULL
15-
16-
Warning: random_bytes(): Length must be greater than 0 in %s on line %d
17-
bool(false)
20+
--EXPECT--
21+
random_bytes() expects exactly 1 parameter, 0 given
22+
Length must be greater than 0

ext/standard/tests/random/random_int.phpt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,11 @@ var_dump($x >= 10 && $x <= 100);
1111

1212
var_dump(random_int(-1000, -1) < 0);
1313

14+
var_dump(random_int(42,42));
15+
1416
?>
1517
--EXPECT--
1618
bool(true)
1719
bool(true)
1820
bool(true)
21+
int(42)

ext/standard/tests/random/random_int_error.phpt

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,26 @@ Test error operation of random_int()
44
<?php
55
//-=-=-=-
66

7-
var_dump(random_int());
7+
try {
8+
$randomInt = random_int();
9+
} catch (TypeError $e) {
10+
echo $e->getMessage().PHP_EOL;
11+
}
812

9-
var_dump(random_int(10));
13+
try {
14+
$randomInt = random_int(42);
15+
} catch (TypeError $e) {
16+
echo $e->getMessage().PHP_EOL;
17+
}
1018

11-
var_dump(random_int(10, 0));
19+
try {
20+
$randomInt = random_int(42,0);
21+
} catch (Error $e) {
22+
echo $e->getMessage().PHP_EOL;
23+
}
1224

1325
?>
14-
--EXPECTF--
15-
Warning: random_int() expects exactly 2 parameters, 0 given in %s on line %d
16-
NULL
17-
18-
Warning: random_int() expects exactly 2 parameters, 1 given in %s on line %d
19-
NULL
20-
21-
Warning: random_int(): Minimum value must be less than the maximum value in %s on line %d
22-
bool(false)
26+
--EXPECT--
27+
random_int() expects exactly 2 parameters, 0 given
28+
random_int() expects exactly 2 parameters, 1 given
29+
Minimum value must be less than or equal to the maximum value

0 commit comments

Comments
 (0)