]> granicus.if.org Git - php/commitdiff
Expose php_random_bytes as a first-class API within internals
authorAnthony Ferrara <ircmaxell@gmail.com>
Tue, 8 Dec 2015 12:12:45 +0000 (13:12 +0100)
committerAnatol Belski <ab@php.net>
Tue, 8 Dec 2015 12:12:45 +0000 (13:12 +0100)
This also defines two macros: php_random_bytes_throw and php_random_bytes_silent depending on use case which will throw exceptions or not respectively

ext/standard/php_random.h
ext/standard/random.c

index ecf9c7135ba609ecabb1b52a8c903788f9dcd33a..a07dbf935ec82324aa5fd87ccc8ad911093038cf 100644 (file)
@@ -31,6 +31,11 @@ typedef struct {
        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;
index bf3a2bc32199b04b850d5991d07a58ae4f97a13b..5fbb46018442ad088eb304bafd8b75e9cd976683 100644 (file)
@@ -82,12 +82,14 @@ PHP_MSHUTDOWN_FUNCTION(random)
 
 /* {{{ */
 
-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))
@@ -122,7 +124,9 @@ static int php_random_bytes(void *bytes, size_t size)
                                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;
                }
 
@@ -139,7 +143,9 @@ static int php_random_bytes(void *bytes, size_t size)
                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? */
@@ -151,7 +157,9 @@ static int php_random_bytes(void *bytes, size_t size)
 # 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;
@@ -166,7 +174,9 @@ static int php_random_bytes(void *bytes, size_t size)
        }
 
        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
@@ -193,7 +203,7 @@ PHP_FUNCTION(random_bytes)
 
        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;
        }
@@ -228,7 +238,7 @@ PHP_FUNCTION(random_int)
 
        umax = max - min;
 
-       if (php_random_bytes(&result, sizeof(result)) == FAILURE) {
+       if (php_random_bytes_throw(&result, sizeof(result)) == FAILURE) {
                return;
        }
 
@@ -247,7 +257,7 @@ PHP_FUNCTION(random_int)
 
                /* 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;
                        }
                }