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

@ -1628,6 +1628,15 @@ ZEND_API void object_properties_load(zend_object *object, HashTable *properties)
zend_hash_update(object->properties, key, &tmp);
}
} else {
if (UNEXPECTED(object->ce->ce_flags & ZEND_ACC_NO_DYNAMIC_PROPERTIES)) {
zend_throw_error(NULL, "Cannot create dynamic property %s::$%s",
ZSTR_VAL(object->ce->name), property_info != ZEND_WRONG_PROPERTY_INFO ? zend_get_unmangled_property_name(key): "");
return;
} else if (!(object->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
zend_error(E_DEPRECATED, "Creation of dynamic property %s::$%s is deprecated",
ZSTR_VAL(object->ce->name), property_info != ZEND_WRONG_PROPERTY_INFO ? zend_get_unmangled_property_name(key): "");
}
if (!object->properties) {
rebuild_object_properties(object);
}
@ -1635,6 +1644,14 @@ ZEND_API void object_properties_load(zend_object *object, HashTable *properties)
zval_add_ref(prop);
}
} else {
if (UNEXPECTED(object->ce->ce_flags & ZEND_ACC_NO_DYNAMIC_PROPERTIES)) {
zend_throw_error(NULL, "Cannot create dynamic property %s::$" ZEND_LONG_FMT, ZSTR_VAL(object->ce->name), h);
return;
} else if (!(object->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
zend_error(E_DEPRECATED, "Creation of dynamic property %s::$" ZEND_LONG_FMT " is deprecated",
ZSTR_VAL(object->ce->name), h);
}
if (!object->properties) {
rebuild_object_properties(object);
}