Fix GH-9186 @strict-properties can be bypassed using unserialization (#9354)

* Emit deprecation warnings when adding dynamic properties to classes during unserialization - this will become an Error in php 9.0.
  (Adding dynamic properties in other contexts was already a deprecation warning - the use case of unserialization was overlooked)
* Throw an error when attempting to add a dynamic property to a `readonly` class when unserializing
* Add new serialization methods `__serialize`/`__unserialize` for SplFixedArray to avoid creating deprecated dynamic
  properties that would then be added to the backing fixed-size array
* Don't add named dynamic/declared properties (e.g. $obj->foo) of SplFixedArray to the backing array when unserializing
* Update tests to declare properties or to expect the deprecation warning
* Add news entry

Co-authored-by: Tyson Andre <tysonandre775@hotmail.com>
This commit is contained in:
Máté Kocsis 2022-08-30 13:46:32 +02:00 committed by GitHub
parent 8d78dce902
commit adb45a63c0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
36 changed files with 271 additions and 22 deletions

View file

@ -90,7 +90,7 @@ 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;
@ -104,7 +104,7 @@ PHP_METHOD(Random_Randomizer, nextInt)
zend_throw_exception(random_ce_Random_RandomException, "Generated value exceeds size of int", 0);
RETURN_THROWS();
}
RETURN_LONG((zend_long) (result >> 1));
}
/* }}} */
@ -278,6 +278,10 @@ PHP_METHOD(Random_Randomizer, __unserialize)
RETURN_THROWS();
}
object_properties_load(&randomizer->std, Z_ARRVAL_P(members_zv));
if (EG(exception)) {
zend_throw_exception(NULL, "Invalid serialization data for Random\\Randomizer object", 0);
RETURN_THROWS();
}
zengine = zend_read_property(randomizer->std.ce, &randomizer->std, "engine", strlen("engine"), 1, NULL);
if (Z_TYPE_P(zengine) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(zengine), random_ce_Random_Engine)) {