mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Clean up the implementation of Randomizer::__construct() (#9222)
* Verify that the engine doesn't change in construct_twice.phpt * Clean up the implementation of Randomizer::__construct() Instead of manually checking whether the constructor was already called, we rely on the `readonly` modifier of the `$engine` property. Additionally use `object_init_ex()` instead of manually calling `->create_object()`.
This commit is contained in:
parent
54e406cc50
commit
a6922fdecd
2 changed files with 33 additions and 24 deletions
|
@ -62,32 +62,30 @@ static inline void randomizer_common_init(php_random_randomizer *randomizer, zen
|
||||||
PHP_METHOD(Random_Randomizer, __construct)
|
PHP_METHOD(Random_Randomizer, __construct)
|
||||||
{
|
{
|
||||||
php_random_randomizer *randomizer = Z_RANDOM_RANDOMIZER_P(ZEND_THIS);
|
php_random_randomizer *randomizer = Z_RANDOM_RANDOMIZER_P(ZEND_THIS);
|
||||||
zend_object *engine_object = NULL;
|
zval engine;
|
||||||
zval zengine_object;
|
zval *param_engine = NULL;
|
||||||
|
|
||||||
ZEND_PARSE_PARAMETERS_START(0, 1)
|
ZEND_PARSE_PARAMETERS_START(0, 1)
|
||||||
Z_PARAM_OPTIONAL
|
Z_PARAM_OPTIONAL
|
||||||
Z_PARAM_OBJ_OF_CLASS_OR_NULL(engine_object, random_ce_Random_Engine);
|
Z_PARAM_OBJECT_OF_CLASS_OR_NULL(param_engine, random_ce_Random_Engine);
|
||||||
ZEND_PARSE_PARAMETERS_END();
|
ZEND_PARSE_PARAMETERS_END();
|
||||||
|
|
||||||
if (randomizer->algo) {
|
if (param_engine != NULL) {
|
||||||
zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot call constructor twice");
|
ZVAL_COPY(&engine, param_engine);
|
||||||
|
} else {
|
||||||
|
/* Create default RNG instance */
|
||||||
|
object_init_ex(&engine, random_ce_Random_Engine_Secure);
|
||||||
|
}
|
||||||
|
|
||||||
|
zend_update_property(random_ce_Random_Randomizer, Z_OBJ_P(ZEND_THIS), "engine", strlen("engine"), &engine);
|
||||||
|
|
||||||
|
OBJ_RELEASE(Z_OBJ_P(&engine));
|
||||||
|
|
||||||
|
if (EG(exception)) {
|
||||||
RETURN_THROWS();
|
RETURN_THROWS();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create default RNG instance */
|
randomizer_common_init(randomizer, Z_OBJ_P(&engine));
|
||||||
if (!engine_object) {
|
|
||||||
engine_object = random_ce_Random_Engine_Secure->create_object(random_ce_Random_Engine_Secure);
|
|
||||||
|
|
||||||
/* No need self-refcount */
|
|
||||||
GC_DELREF(engine_object);
|
|
||||||
}
|
|
||||||
|
|
||||||
ZVAL_OBJ(&zengine_object, engine_object);
|
|
||||||
|
|
||||||
zend_update_property(random_ce_Random_Randomizer, Z_OBJ_P(ZEND_THIS), "engine", strlen("engine"), &zengine_object);
|
|
||||||
|
|
||||||
randomizer_common_init(randomizer, engine_object);
|
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
|
|
@ -13,28 +13,39 @@ final class UserEngine implements \Random\Engine
|
||||||
|
|
||||||
try {
|
try {
|
||||||
(new \Random\Randomizer())->__construct();
|
(new \Random\Randomizer())->__construct();
|
||||||
} catch (\BadMethodCallException $e) {
|
} catch (\Error $e) {
|
||||||
echo $e->getMessage() . PHP_EOL;
|
echo $e->getMessage() . PHP_EOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$r = new \Random\Randomizer(new \Random\Engine\Xoshiro256StarStar());
|
$r = new \Random\Randomizer(new \Random\Engine\Xoshiro256StarStar());
|
||||||
$r->__construct(new \Random\Engine\PcgOneseq128XslRr64());
|
$r->__construct(new \Random\Engine\PcgOneseq128XslRr64());
|
||||||
} catch (\BadMethodCallException $e) {
|
} catch (\Error $e) {
|
||||||
echo $e->getMessage() . PHP_EOL;
|
echo $e->getMessage() . PHP_EOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$r = new \Random\Randomizer(new \UserEngine());
|
$r = new \Random\Randomizer(new \UserEngine());
|
||||||
$r->__construct(new \UserEngine());
|
$r->__construct(new \UserEngine());
|
||||||
} catch (\BadMethodCallException $e) {
|
} catch (\Error $e) {
|
||||||
echo $e->getMessage() . PHP_EOL;
|
echo $e->getMessage() . PHP_EOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$r = new \Random\Randomizer(new \Random\Engine\Xoshiro256StarStar());
|
||||||
|
$r->__construct(new \UserEngine());
|
||||||
|
} catch (\Error $e) {
|
||||||
|
echo $e->getMessage(), PHP_EOL;
|
||||||
|
}
|
||||||
|
|
||||||
|
var_dump($r->engine::class);
|
||||||
|
|
||||||
die('success');
|
die('success');
|
||||||
?>
|
?>
|
||||||
--EXPECT--
|
--EXPECT--
|
||||||
Cannot call constructor twice
|
Cannot modify readonly property Random\Randomizer::$engine
|
||||||
Cannot call constructor twice
|
Cannot modify readonly property Random\Randomizer::$engine
|
||||||
Cannot call constructor twice
|
Cannot modify readonly property Random\Randomizer::$engine
|
||||||
|
Cannot modify readonly property Random\Randomizer::$engine
|
||||||
|
string(32) "Random\Engine\Xoshiro256StarStar"
|
||||||
success
|
success
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue