2626
2727#include "php.h"
2828
29- #include "ext/spl/spl_exceptions.h"
3029#include "Zend/zend_exceptions.h"
3130
3231#include "php_random.h"
@@ -74,8 +73,13 @@ PHPAPI zend_class_entry *random_ce_Random_Engine_Mt19937;
7473PHPAPI zend_class_entry * random_ce_Random_Engine_PcgOneseq128XslRr64 ;
7574PHPAPI zend_class_entry * random_ce_Random_Engine_Xoshiro256StarStar ;
7675PHPAPI zend_class_entry * random_ce_Random_Engine_Secure ;
76+
7777PHPAPI zend_class_entry * random_ce_Random_Randomizer ;
7878
79+ PHPAPI zend_class_entry * random_ce_Random_RandomError ;
80+ PHPAPI zend_class_entry * random_ce_Random_BrokenRandomEngineError ;
81+ PHPAPI zend_class_entry * random_ce_Random_RandomException ;
82+
7983static zend_object_handlers random_engine_mt19937_object_handlers ;
8084static zend_object_handlers random_engine_pcgoneseq128xslrr64_object_handlers ;
8185static zend_object_handlers random_engine_xoshiro256starstar_object_handlers ;
@@ -121,7 +125,7 @@ static inline uint32_t rand_range32(const php_random_algo *algo, php_random_stat
121125 while (UNEXPECTED (result > limit )) {
122126 /* If the requirements cannot be met in a cycles, return fail */
123127 if (++ count > RANDOM_RANGE_ATTEMPTS ) {
124- zend_throw_error (NULL , "Failed to generate an acceptable random number in %d attempts" , RANDOM_RANGE_ATTEMPTS );
128+ zend_throw_error (random_ce_Random_BrokenRandomEngineError , "Failed to generate an acceptable random number in %d attempts" , RANDOM_RANGE_ATTEMPTS );
125129 return 0 ;
126130 }
127131
@@ -177,7 +181,7 @@ static inline uint64_t rand_range64(const php_random_algo *algo, php_random_stat
177181 while (UNEXPECTED (result > limit )) {
178182 /* If the requirements cannot be met in a cycles, return fail */
179183 if (++ count > RANDOM_RANGE_ATTEMPTS ) {
180- zend_throw_error (NULL , "Failed to generate an acceptable random number in %d attempts" , RANDOM_RANGE_ATTEMPTS );
184+ zend_throw_error (random_ce_Random_BrokenRandomEngineError , "Failed to generate an acceptable random number in %d attempts" , RANDOM_RANGE_ATTEMPTS );
181185 return 0 ;
182186 }
183187
@@ -470,7 +474,7 @@ PHPAPI int php_random_bytes(void *bytes, size_t size, bool should_throw)
470474 /* Defer to CryptGenRandom on Windows */
471475 if (php_win32_get_random_bytes (bytes , size ) == FAILURE ) {
472476 if (should_throw ) {
473- zend_throw_exception (zend_ce_exception , "Failed to retrieve randomness from the operating system (BCryptGenRandom)" , 0 );
477+ zend_throw_exception (random_ce_Random_RandomException , "Failed to retrieve randomness from the operating system (BCryptGenRandom)" , 0 );
474478 }
475479 return FAILURE ;
476480 }
@@ -483,7 +487,7 @@ PHPAPI int php_random_bytes(void *bytes, size_t size, bool should_throw)
483487 */
484488 if (CCRandomGenerateBytes (bytes , size ) != kCCSuccess ) {
485489 if (should_throw ) {
486- zend_throw_exception (zend_ce_exception , "Failed to retrieve randomness from the operating system (CCRandomGenerateBytes)" , 0 );
490+ zend_throw_exception (random_ce_Random_RandomException , "Failed to retrieve randomness from the operating system (CCRandomGenerateBytes)" , 0 );
487491 }
488492 return FAILURE ;
489493 }
@@ -548,9 +552,9 @@ PHPAPI int php_random_bytes(void *bytes, size_t size, bool should_throw)
548552 if (fd < 0 ) {
549553 if (should_throw ) {
550554 if (errno != 0 ) {
551- zend_throw_exception_ex (zend_ce_exception , 0 , "Cannot open /dev/urandom: %s" , strerror (errno ));
555+ zend_throw_exception_ex (random_ce_Random_RandomException , 0 , "Cannot open /dev/urandom: %s" , strerror (errno ));
552556 } else {
553- zend_throw_exception_ex (zend_ce_exception , 0 , "Cannot open /dev/urandom" );
557+ zend_throw_exception_ex (random_ce_Random_RandomException , 0 , "Cannot open /dev/urandom" );
554558 }
555559 }
556560 return FAILURE ;
@@ -568,9 +572,9 @@ PHPAPI int php_random_bytes(void *bytes, size_t size, bool should_throw)
568572 close (fd );
569573 if (should_throw ) {
570574 if (errno != 0 ) {
571- zend_throw_exception_ex (zend_ce_exception , 0 , "Error reading from /dev/urandom: %s" , strerror (errno ));
575+ zend_throw_exception_ex (random_ce_Random_RandomException , 0 , "Error reading from /dev/urandom: %s" , strerror (errno ));
572576 } else {
573- zend_throw_exception_ex (zend_ce_exception , 0 , "Error reading from /dev/urandom" );
577+ zend_throw_exception_ex (random_ce_Random_RandomException , 0 , "Error reading from /dev/urandom" );
574578 }
575579 }
576580 return FAILURE ;
@@ -589,9 +593,9 @@ PHPAPI int php_random_bytes(void *bytes, size_t size, bool should_throw)
589593 if (read_bytes < size ) {
590594 if (should_throw ) {
591595 if (errno != 0 ) {
592- zend_throw_exception_ex (zend_ce_exception , 0 , "Could not gather sufficient random data: %s" , strerror (errno ));
596+ zend_throw_exception_ex (random_ce_Random_RandomException , 0 , "Could not gather sufficient random data: %s" , strerror (errno ));
593597 } else {
594- zend_throw_exception_ex (zend_ce_exception , 0 , "Could not gather sufficient random data" );
598+ zend_throw_exception_ex (random_ce_Random_RandomException , 0 , "Could not gather sufficient random data" );
595599 }
596600 }
597601 return FAILURE ;
@@ -832,6 +836,15 @@ PHP_MINIT_FUNCTION(random)
832836 /* Random\CryptoSafeEngine */
833837 random_ce_Random_CryptoSafeEngine = register_class_Random_CryptoSafeEngine (random_ce_Random_Engine );
834838
839+ /* Random\RandomError */
840+ random_ce_Random_RandomError = register_class_Random_RandomError (zend_ce_error );
841+
842+ /* Random\BrokenRandomEngineError */
843+ random_ce_Random_BrokenRandomEngineError = register_class_Random_BrokenRandomEngineError (random_ce_Random_RandomError );
844+
845+ /* Random\RandomException */
846+ random_ce_Random_RandomException = register_class_Random_RandomException (zend_ce_exception );
847+
835848 /* Random\Engine\Mt19937 */
836849 random_ce_Random_Engine_Mt19937 = register_class_Random_Engine_Mt19937 (random_ce_Random_Engine );
837850 random_ce_Random_Engine_Mt19937 -> create_object = php_random_engine_mt19937_new ;
0 commit comments