diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2020-05-14 11:51:36 +0200 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2020-06-24 11:52:36 +0200 |
commit | 653e4ea1c57def2d5cd75b7da9e3943a841b7d6c (patch) | |
tree | 479717f0e9a8eb24e733990512304fc7209ca45d /Zend/zend_weakrefs.c | |
parent | 2a28589c7def80ecc7bb3417a8853df6b7860b46 (diff) | |
download | php-git-653e4ea1c57def2d5cd75b7da9e3943a841b7d6c.tar.gz |
Add flag to forbid dynamic property creation on internal classes
While performing resource -> object migrations, we're adding
defensive classes that are final, non-serializable and non-clonable
(unless they are, of course). This path adds a ZEND_ACC_NO_DYNAMIC_PROPERTIES
flag, that also forbids the creation of dynamic properties on these objects.
This is a subset of #3931 and targeted at internal usage only
(though may be extended to userland at some point in the future).
It's already possible to achieve this (what the removed
WeakRef/WeakMap code does), but there's some caveats: First, this
simple approach is only possible if the class has no declared
properties, otherwise it's necessary to special-case those
properties. Second, it's easy to make it overly strict, e.g. by
forbidding isset($obj->prop) as well. And finally, it requires a
lot of boilerplate code for each class.
Closes GH-5572.
Diffstat (limited to 'Zend/zend_weakrefs.c')
-rw-r--r-- | Zend/zend_weakrefs.c | 47 |
1 files changed, 2 insertions, 45 deletions
diff --git a/Zend/zend_weakrefs.c b/Zend/zend_weakrefs.c index b633a57e9f..0e94617dbf 100644 --- a/Zend/zend_weakrefs.c +++ b/Zend/zend_weakrefs.c @@ -234,39 +234,6 @@ static void zend_weakref_free(zend_object *zo) { zend_object_std_dtor(&wr->std); } -#define zend_weakref_unsupported(object, thing) \ - zend_throw_error(NULL, "%s objects do not support " thing, ZSTR_VAL(object->ce->name)); - -static ZEND_COLD zval* zend_weakref_no_write(zend_object *object, zend_string *member, zval *value, void **rtc) { - zend_weakref_unsupported(object, "properties"); - - return &EG(uninitialized_zval); -} - -static ZEND_COLD zval* zend_weakref_no_read(zend_object *object, zend_string *member, int type, void **rtc, zval *rv) { - if (!EG(exception)) { - zend_weakref_unsupported(object, "properties"); - } - - return &EG(uninitialized_zval); -} - -static ZEND_COLD zval *zend_weakref_no_read_ptr(zend_object *object, zend_string *member, int type, void **rtc) { - zend_weakref_unsupported(object, "property references"); - return NULL; -} - -static ZEND_COLD int zend_weakref_no_isset(zend_object *object, zend_string *member, int hse, void **rtc) { - if (hse != 2) { - zend_weakref_unsupported(object, "properties"); - } - return 0; -} - -static ZEND_COLD void zend_weakref_no_unset(zend_object *object, zend_string *member, void **rtc) { - zend_weakref_unsupported(object, "properties"); -} - ZEND_COLD ZEND_METHOD(WeakReference, __construct) { zend_throw_error(NULL, @@ -615,7 +582,7 @@ void zend_register_weakref_ce(void) /* {{{ */ INIT_CLASS_ENTRY(ce, "WeakReference", class_WeakReference_methods); zend_ce_weakref = zend_register_internal_class(&ce); - zend_ce_weakref->ce_flags |= ZEND_ACC_FINAL; + zend_ce_weakref->ce_flags |= ZEND_ACC_FINAL | ZEND_ACC_NO_DYNAMIC_PROPERTIES; zend_ce_weakref->create_object = zend_weakref_new; zend_ce_weakref->serialize = zend_class_serialize_deny; @@ -625,16 +592,11 @@ void zend_register_weakref_ce(void) /* {{{ */ zend_weakref_handlers.offset = XtOffsetOf(zend_weakref, std); zend_weakref_handlers.free_obj = zend_weakref_free; - zend_weakref_handlers.read_property = zend_weakref_no_read; - zend_weakref_handlers.write_property = zend_weakref_no_write; - zend_weakref_handlers.has_property = zend_weakref_no_isset; - zend_weakref_handlers.unset_property = zend_weakref_no_unset; - zend_weakref_handlers.get_property_ptr_ptr = zend_weakref_no_read_ptr; zend_weakref_handlers.clone_obj = NULL; INIT_CLASS_ENTRY(ce, "WeakMap", class_WeakMap_methods); zend_ce_weakmap = zend_register_internal_class(&ce); - zend_ce_weakmap->ce_flags |= ZEND_ACC_FINAL; + zend_ce_weakmap->ce_flags |= ZEND_ACC_FINAL | ZEND_ACC_NO_DYNAMIC_PROPERTIES; zend_ce_weakmap->create_object = zend_weakmap_create_object; zend_ce_weakmap->get_iterator = zend_weakmap_get_iterator; @@ -656,11 +618,6 @@ void zend_register_weakref_ce(void) /* {{{ */ zend_weakmap_handlers.get_properties_for = zend_weakmap_get_properties_for; zend_weakmap_handlers.get_gc = zend_weakmap_get_gc; zend_weakmap_handlers.clone_obj = zend_weakmap_clone_obj; - zend_weakmap_handlers.read_property = zend_weakref_no_read; - zend_weakmap_handlers.write_property = zend_weakref_no_write; - zend_weakmap_handlers.has_property = zend_weakref_no_isset; - zend_weakmap_handlers.unset_property = zend_weakref_no_unset; - zend_weakmap_handlers.get_property_ptr_ptr = zend_weakref_no_read_ptr; } /* }}} */ |