mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
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:
parent
59d257d1ae
commit
4e92c74654
7 changed files with 55 additions and 34 deletions
2
NEWS
2
NEWS
|
@ -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)
|
||||
|
|
|
@ -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 {}
|
||||
|
||||
|
|
8
ext/random/random_arginfo.h
generated
8
ext/random/random_arginfo.h
generated
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue