random: split Randomizer::getInt() without argument to Randomizer::nextInt()

Since argument overloading is not safe for reflection, the method needed
to be split appropriately.

Co-authored-by: Tim Düsterhus <timwolla@googlemail.com>

Closes GH-9057.
This commit is contained in:
zeriyoshi 2022-07-30 14:03:39 +02:00 committed by Christoph M. Becker
parent 59d257d1ae
commit 4e92c74654
No known key found for this signature in database
GPG key ID: D66C9593118BCCB6
7 changed files with 55 additions and 34 deletions

2
NEWS
View file

@ -41,6 +41,8 @@ PHP NEWS
call twice) (zeriyoshi)
. Change Mt19937 to throw a ValueError instead of InvalidArgumentException
for invalid $mode. (timwolla)
. Splitted Random\Randomizer::getInt() (without arguments) to
Random\Randomizer::nextInt(). (zeriyoshi)
- Sockets:
. Added SOL_FILTER socket option for Solaris. (David Carlier)

View file

@ -131,7 +131,9 @@ namespace Random
public function __construct(?Engine $engine = null) {}
public function getInt(int $min = UNKNOWN, int $max = UNKNOWN): int {}
public function nextInt(): int {}
public function getInt(int $min, int $max): int {}
public function getBytes(int $length): string {}

View file

@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
* Stub hash: c072111a2483473d47d7d77d7d80aea84c663c7a */
* Stub hash: 9727755f39598fe1fbc16b501063cd3c30279ff9 */
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_lcg_value, 0, 0, IS_DOUBLE, 0)
ZEND_END_ARG_INFO()
@ -91,7 +91,9 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Random_Randomizer___construct, 0, 0, 0)
ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, engine, Random\\Engine, 1, "null")
ZEND_END_ARG_INFO()
#define arginfo_class_Random_Randomizer_getInt arginfo_rand
#define arginfo_class_Random_Randomizer_nextInt arginfo_mt_getrandmax
#define arginfo_class_Random_Randomizer_getInt arginfo_random_int
#define arginfo_class_Random_Randomizer_getBytes arginfo_random_bytes
@ -131,6 +133,7 @@ ZEND_METHOD(Random_Engine_Xoshiro256StarStar, __construct);
ZEND_METHOD(Random_Engine_Xoshiro256StarStar, jump);
ZEND_METHOD(Random_Engine_Xoshiro256StarStar, jumpLong);
ZEND_METHOD(Random_Randomizer, __construct);
ZEND_METHOD(Random_Randomizer, nextInt);
ZEND_METHOD(Random_Randomizer, getInt);
ZEND_METHOD(Random_Randomizer, getBytes);
ZEND_METHOD(Random_Randomizer, shuffleArray);
@ -206,6 +209,7 @@ static const zend_function_entry class_Random_CryptoSafeEngine_methods[] = {
static const zend_function_entry class_Random_Randomizer_methods[] = {
ZEND_ME(Random_Randomizer, __construct, arginfo_class_Random_Randomizer___construct, ZEND_ACC_PUBLIC)
ZEND_ME(Random_Randomizer, nextInt, arginfo_class_Random_Randomizer_nextInt, ZEND_ACC_PUBLIC)
ZEND_ME(Random_Randomizer, getInt, arginfo_class_Random_Randomizer_getInt, ZEND_ACC_PUBLIC)
ZEND_ME(Random_Randomizer, getBytes, arginfo_class_Random_Randomizer_getBytes, ZEND_ACC_PUBLIC)
ZEND_ME(Random_Randomizer, shuffleArray, arginfo_class_Random_Randomizer_shuffleArray, ZEND_ACC_PUBLIC)

View file

@ -91,26 +91,34 @@ PHP_METHOD(Random_Randomizer, __construct)
}
/* }}} */
/* {{{ Generate positive random number */
PHP_METHOD(Random_Randomizer, nextInt)
{
php_random_randomizer *randomizer = Z_RANDOM_RANDOMIZER_P(ZEND_THIS);
uint64_t result;
ZEND_PARSE_PARAMETERS_NONE();
result = randomizer->algo->generate(randomizer->status);
if (randomizer->status->last_generated_size > sizeof(zend_long)) {
zend_throw_exception(spl_ce_RuntimeException, "Generated value exceeds size of int", 0);
RETURN_THROWS();
}
if (EG(exception)) {
zend_throw_exception(spl_ce_RuntimeException, "Random number generation failed", 0);
RETURN_THROWS();
}
RETURN_LONG((zend_long) (result >> 1));
}
/* }}} */
/* {{{ Generate random number in range */
PHP_METHOD(Random_Randomizer, getInt)
{
php_random_randomizer *randomizer = Z_RANDOM_RANDOMIZER_P(ZEND_THIS);
uint64_t result;
zend_long min, max;
int argc = ZEND_NUM_ARGS();
if (argc == 0) {
result = randomizer->algo->generate(randomizer->status);
if (randomizer->status->last_generated_size > sizeof(zend_long)) {
zend_throw_exception(spl_ce_RuntimeException, "Generated value exceeds size of int", 0);
RETURN_THROWS();
}
if (EG(exception)) {
zend_throw_exception(spl_ce_RuntimeException, "Random number generation failed", 0);
RETURN_THROWS();
}
RETURN_LONG((zend_long) (result >> 1));
}
ZEND_PARSE_PARAMETERS_START(2, 2)
Z_PARAM_LONG(min)

View file

@ -27,6 +27,17 @@ $engines[] = new UserEngine();
foreach ($engines as $engine) {
$randomizer = new Random\Randomizer($engine);
// nextInt
for ($i = 0; $i < 1000; $i++) {
try {
$randomizer->nextInt();
} catch (\RuntimeException $e) {
if ($e->getMessage() !== 'Generated value exceeds size of int') {
die($engine::class . ": nextInt: failure: {$e->getMessage()}");
}
}
}
// getInt
for ($i = 0; $i < 1000; $i++) {
$result = $randomizer->getInt(-50, 50);
@ -39,7 +50,7 @@ foreach ($engines as $engine) {
for ($i = 0; $i < 1000; $i++) {
$length = \random_int(1, 1024);
if (\strlen($randomizer->getBytes($length)) !== $length) {
die($engine::class . ': getBytes: failure.');
die($engine::class . ': getBytes: failure');
}
}
@ -53,14 +64,14 @@ foreach ($engines as $engine) {
}
}
die($engine::class . ': shuffleArray: failure.');
die($engine::class . ': shuffleArray: failure');
})();
// shuffleBytes
$string = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.';
$shuffled_string = $randomizer->shuffleBytes($string);
if ($string === $shuffled_string) {
die($engine::class . ': shuffleBytes: failure.');
die($engine::class . ': shuffleBytes: failure');
}
}

View file

@ -6,7 +6,7 @@ Random: Randomizer: Compatibility: Mt19937
$randomizer = new \Random\Randomizer(new \Random\Engine\Mt19937(1234, \MT_RAND_PHP));
\mt_srand(1234, \MT_RAND_PHP);
for ($i = 0; $i < 1000; $i++) {
if ($randomizer->getInt() !== \mt_rand()) {
if ($randomizer->nextInt() !== \mt_rand()) {
die('failure');
}
}
@ -14,7 +14,7 @@ for ($i = 0; $i < 1000; $i++) {
$randomizer = new \Random\Randomizer(new \Random\Engine\Mt19937(1234, \MT_RAND_MT19937));
\mt_srand(1234, \MT_RAND_MT19937);
for ($i = 0; $i < 1000; $i++) {
if ($randomizer->getInt() !== \mt_rand()) {
if ($randomizer->nextInt() !== \mt_rand()) {
die('failure');
}
}

View file

@ -15,8 +15,8 @@ $user_randomizer = new \Random\Randomizer(new class () implements \Random\Engine
}
});
for ($i = 0; $i < 1000; $i++) {
$native = $native_randomizer->getInt();
$user = $user_randomizer->getInt();
$native = $native_randomizer->nextInt();
$user = $user_randomizer->nextInt();
if ($native !== $user) {
die("failure Mt19937 i: {$i} native: {$native} user: {$user}");
}
@ -36,16 +36,13 @@ try {
});
for ($i = 0; $i < 1000; $i++) {
$native = $native_randomizer->getInt();
$user = $user_randomizer->getInt();
$native = $native_randomizer->nextInt();
$user = $user_randomizer->nextInt();
if ($native !== $user) {
die("failure PcgOneseq128XslRr64 i: {$i} native: {$native} user: {$user}");
}
}
} catch (\RuntimeException $e) {
if (\PHP_INT_SIZE >= 8) {
throw $e;
}
if ($e->getMessage() !== 'Generated value exceeds size of int') {
throw $e;
}
@ -65,16 +62,13 @@ try {
});
for ($i = 0; $i < 1000; $i++) {
$native = $native_randomizer->getInt();
$user = $user_randomizer->getInt();
$native = $native_randomizer->nextInt();
$user = $user_randomizer->nextInt();
if ($native !== $user) {
die("failure Xoshiro256StarStar i: {$i} native: {$native} user: {$user}");
}
}
} catch (\RuntimeException $e) {
if (\PHP_INT_SIZE >= 8) {
throw $e;
}
if ($e->getMessage() !== 'Generated value exceeds size of int') {
throw $e;
}