int fd;
} php_random_globals;
+#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)
+
+PHPAPI int php_random_bytes(void *bytes, size_t size, zend_bool should_throw);
+
#ifdef ZTS
# define RANDOM_G(v) ZEND_TSRMG(random_globals_id, php_random_globals *, v)
extern PHPAPI int random_globals_id;
/* {{{ */
-static int php_random_bytes(void *bytes, size_t size)
+PHPAPI int php_random_bytes(void *bytes, size_t size, zend_bool should_throw)
{
#if PHP_WIN32
/* Defer to CryptGenRandom on Windows */
if (php_win32_get_random_bytes(bytes, size) == FAILURE) {
- zend_throw_exception(zend_ce_exception, "Could not gather sufficient random data", 0);
+ if (should_throw) {
+ zend_throw_exception(zend_ce_exception, "Could not gather sufficient random data", 0);
+ }
return FAILURE;
}
#elif HAVE_DECL_ARC4RANDOM_BUF && ((defined(__OpenBSD__) && OpenBSD >= 201405) || (defined(__NetBSD__) && __NetBSD_Version__ >= 700000001))
php_random_bytes should be terminated by the exception instead
of proceeding to demand more entropy.
*/
- zend_throw_exception(zend_ce_exception, "Could not gather sufficient random data", errno);
+ if (should_throw) {
+ zend_throw_exception(zend_ce_exception, "Could not gather sufficient random data", errno);
+ }
return FAILURE;
}
fd = open("/dev/urandom", O_RDONLY);
#endif
if (fd < 0) {
- zend_throw_exception(zend_ce_exception, "Cannot open source device", 0);
+ if (should_throw) {
+ zend_throw_exception(zend_ce_exception, "Cannot open source device", 0);
+ }
return FAILURE;
}
/* Does the file exist and is it a character device? */
# endif
) {
close(fd);
- zend_throw_exception(zend_ce_exception, "Error reading from source device", 0);
+ if (should_throw) {
+ zend_throw_exception(zend_ce_exception, "Error reading from source device", 0);
+ }
return FAILURE;
}
RANDOM_G(fd) = fd;
}
if (read_bytes < size) {
- zend_throw_exception(zend_ce_exception, "Could not gather sufficient random data", 0);
+ if (should_throw) {
+ zend_throw_exception(zend_ce_exception, "Could not gather sufficient random data", 0);
+ }
return FAILURE;
}
#endif
bytes = zend_string_alloc(size, 0);
- if (php_random_bytes(ZSTR_VAL(bytes), size) == FAILURE) {
+ if (php_random_bytes_throw(ZSTR_VAL(bytes), size) == FAILURE) {
zend_string_release(bytes);
return;
}
umax = max - min;
- if (php_random_bytes(&result, sizeof(result)) == FAILURE) {
+ if (php_random_bytes_throw(&result, sizeof(result)) == FAILURE) {
return;
}
/* Discard numbers over the limit to avoid modulo bias */
while (result > limit) {
- if (php_random_bytes(&result, sizeof(result)) == FAILURE) {
+ if (php_random_bytes_throw(&result, sizeof(result)) == FAILURE) {
return;
}
}