Skip to content

Commit 1da7422

Browse files
committed
Merge branch 'PHP-7.0'
* PHP-7.0: Expose php_random_bytes as a first-class API within internals
2 parents c58b0cb + 908f67b commit 1da7422

File tree

2 files changed

+24
-9
lines changed

2 files changed

+24
-9
lines changed

ext/standard/php_random.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ typedef struct {
3131
int fd;
3232
} php_random_globals;
3333

34+
#define php_random_bytes_throw(b, s) php_random_bytes((b), (s), 1)
35+
#define php_random_bytes_silent(b, s) php_random_bytes((b), (s), 0)
36+
37+
PHPAPI int php_random_bytes(void *bytes, size_t size, zend_bool should_throw);
38+
3439
#ifdef ZTS
3540
# define RANDOM_G(v) ZEND_TSRMG(random_globals_id, php_random_globals *, v)
3641
extern PHPAPI int random_globals_id;

ext/standard/random.c

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -82,12 +82,14 @@ PHP_MSHUTDOWN_FUNCTION(random)
8282

8383
/* {{{ */
8484

85-
static int php_random_bytes(void *bytes, size_t size)
85+
PHPAPI int php_random_bytes(void *bytes, size_t size, zend_bool should_throw)
8686
{
8787
#if PHP_WIN32
8888
/* Defer to CryptGenRandom on Windows */
8989
if (php_win32_get_random_bytes(bytes, size) == FAILURE) {
90-
zend_throw_exception(zend_ce_exception, "Could not gather sufficient random data", 0);
90+
if (should_throw) {
91+
zend_throw_exception(zend_ce_exception, "Could not gather sufficient random data", 0);
92+
}
9193
return FAILURE;
9294
}
9395
#elif HAVE_DECL_ARC4RANDOM_BUF && ((defined(__OpenBSD__) && OpenBSD >= 201405) || (defined(__NetBSD__) && __NetBSD_Version__ >= 700000001))
@@ -122,7 +124,9 @@ static int php_random_bytes(void *bytes, size_t size)
122124
php_random_bytes should be terminated by the exception instead
123125
of proceeding to demand more entropy.
124126
*/
125-
zend_throw_exception(zend_ce_exception, "Could not gather sufficient random data", errno);
127+
if (should_throw) {
128+
zend_throw_exception(zend_ce_exception, "Could not gather sufficient random data", errno);
129+
}
126130
return FAILURE;
127131
}
128132

@@ -139,7 +143,9 @@ static int php_random_bytes(void *bytes, size_t size)
139143
fd = open("/dev/urandom", O_RDONLY);
140144
#endif
141145
if (fd < 0) {
142-
zend_throw_exception(zend_ce_exception, "Cannot open source device", 0);
146+
if (should_throw) {
147+
zend_throw_exception(zend_ce_exception, "Cannot open source device", 0);
148+
}
143149
return FAILURE;
144150
}
145151
/* Does the file exist and is it a character device? */
@@ -151,7 +157,9 @@ static int php_random_bytes(void *bytes, size_t size)
151157
# endif
152158
) {
153159
close(fd);
154-
zend_throw_exception(zend_ce_exception, "Error reading from source device", 0);
160+
if (should_throw) {
161+
zend_throw_exception(zend_ce_exception, "Error reading from source device", 0);
162+
}
155163
return FAILURE;
156164
}
157165
RANDOM_G(fd) = fd;
@@ -166,7 +174,9 @@ static int php_random_bytes(void *bytes, size_t size)
166174
}
167175

168176
if (read_bytes < size) {
169-
zend_throw_exception(zend_ce_exception, "Could not gather sufficient random data", 0);
177+
if (should_throw) {
178+
zend_throw_exception(zend_ce_exception, "Could not gather sufficient random data", 0);
179+
}
170180
return FAILURE;
171181
}
172182
#endif
@@ -193,7 +203,7 @@ PHP_FUNCTION(random_bytes)
193203

194204
bytes = zend_string_alloc(size, 0);
195205

196-
if (php_random_bytes(ZSTR_VAL(bytes), size) == FAILURE) {
206+
if (php_random_bytes_throw(ZSTR_VAL(bytes), size) == FAILURE) {
197207
zend_string_release(bytes);
198208
return;
199209
}
@@ -228,7 +238,7 @@ PHP_FUNCTION(random_int)
228238

229239
umax = max - min;
230240

231-
if (php_random_bytes(&result, sizeof(result)) == FAILURE) {
241+
if (php_random_bytes_throw(&result, sizeof(result)) == FAILURE) {
232242
return;
233243
}
234244

@@ -247,7 +257,7 @@ PHP_FUNCTION(random_int)
247257

248258
/* Discard numbers over the limit to avoid modulo bias */
249259
while (result > limit) {
250-
if (php_random_bytes(&result, sizeof(result)) == FAILURE) {
260+
if (php_random_bytes_throw(&result, sizeof(result)) == FAILURE) {
251261
return;
252262
}
253263
}

0 commit comments

Comments
 (0)