* Add Random\Random{Error,Exception} and Random\BrokenRandomEngineError
* Throw BrokenRandomEngineError
* Throw RandomException on seeding failure
* Throw RandomException when CSPRNG fails
* Remove unused include from ext/random/engine_combinedlcg.c
* Remove unused include from ext/random/engine_secure.c
* Remove unused include from ext/random/random.c
* [ci skip] Add ext/random Exception hierarchy to NEWS
* [ci skip] Add the change of Exception for random_(int|bytes) to UPGRADING
Whenever ->last_unsafe is set to `true` an exception has been thrown. Thus we
can replace the check for `->last_unsafe` with a check for `EG(exception)`
which is a much more natural way to ommunicate an error up the chain.
* Use `php_random_bytes_throw()` in Secure engine's generate()
This exposes the underlying exception, improving debugging:
Fatal error: Uncaught Exception: Cannot open source device in php-src/test.php:5
Stack trace:
#0 php-src/test.php(5): Random\Engine\Secure->generate()
#1 {main}
Next RuntimeException: Random number generation failed in php-src/test.php:5
Stack trace:
#0 php-src/test.php(5): Random\Engine\Secure->generate()
#1 {main}
thrown in php-src/test.php on line 5
* Use `php_random_int_throw()` in Secure engine's range()
This exposes the underlying exception, improving debugging:
Exception: Cannot open source device in php-src/test.php:17
Stack trace:
#0 php-src/test.php(17): Random\Randomizer->getInt(1, 3)
#1 {main}
Next RuntimeException: Random number generation failed in php-src/test.php:17
Stack trace:
#0 php-src/test.php(17): Random\Randomizer->getInt(1, 3)
#1 {main}
* Throw exception when a user engine returns an empty string
This improves debugging, because the actual reason for the failure is available
as a previous Exception:
DomainException: The returned string must not be empty in php-src/test.php:17
Stack trace:
#0 php-src/test.php(17): Random\Randomizer->getBytes(123)
#1 {main}
Next RuntimeException: Random number generation failed in php-src/test.php:17
Stack trace:
#0 php-src/test.php(17): Random\Randomizer->getBytes(123)
#1 {main}
* Throw exception when the range selector fails to get acceptable numbers in 50 attempts
This improves debugging, because the actual reason for the failure is available
as a previous Exception:
RuntimeException: Failed to generate an acceptable random number in 50 attempts in php-src/test.php:17
Stack trace:
#0 php-src/test.php(17): Random\Randomizer->getInt(1, 3)
#1 {main}
Next RuntimeException: Random number generation failed in php-src/test.php:17
Stack trace:
#0 php-src/test.php(17): Random\Randomizer->getInt(1, 3)
#1 {main}
* Improve user_unsafe test
Select parameters for ->getInt() that will actually lead to unsafe behavior.
* Fix user_unsafe test
If an engine fails once it will be permanently poisoned by setting
`->last_unsafe`. This is undesirable for the test, because it skews the
results.
Fix this by creating a fresh engine for each "assertion".
* Remove duplication in user_unsafe.phpt
* Catch `Throwable` in user_unsafe.phpt
As we print the full stringified exception we implicitly assert the type of the
exception. No need to be overly specific in the catch block.
* Throw an error if an engine returns an empty string
* Throw an Error if range fails to find an acceptable number in 50 attempts
This fixes:
==374077== Use of uninitialised value of size 8
==374077== at 0x532B06: generate (engine_user.c:39)
==374077== by 0x533F71: zim_Random_Randomizer_getBytes (randomizer.c:152)
==374077== by 0x7F581D: ZEND_DO_FCALL_SPEC_RETVAL_USED_HANDLER (zend_vm_execute.h:1885)
==374077== by 0x8725BE: execute_ex (zend_vm_execute.h:55930)
==374077== by 0x877DB4: zend_execute (zend_vm_execute.h:60253)
==374077== by 0x7B0FD4: zend_execute_scripts (zend.c:1770)
==374077== by 0x6F1647: php_execute_script (main.c:2535)
==374077== by 0x937DA4: do_cli (php_cli.c:964)
==374077== by 0x938C3A: main (php_cli.c:1333)
==374077==
==374077== Invalid read of size 8
==374077== at 0x532B06: generate (engine_user.c:39)
==374077== by 0x533F71: zim_Random_Randomizer_getBytes (randomizer.c:152)
==374077== by 0x7F581D: ZEND_DO_FCALL_SPEC_RETVAL_USED_HANDLER (zend_vm_execute.h:1885)
==374077== by 0x8725BE: execute_ex (zend_vm_execute.h:55930)
==374077== by 0x877DB4: zend_execute (zend_vm_execute.h:60253)
==374077== by 0x7B0FD4: zend_execute_scripts (zend.c:1770)
==374077== by 0x6F1647: php_execute_script (main.c:2535)
==374077== by 0x937DA4: do_cli (php_cli.c:964)
==374077== by 0x938C3A: main (php_cli.c:1333)
==374077== Address 0x11 is not stack'd, malloc'd or (recently) free'd