summaryrefslogtreecommitdiff
path: root/Zend/zend_API.c
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2019-10-24 16:36:25 +0200
committerNikita Popov <nikita.ppv@gmail.com>2019-10-25 16:31:45 +0200
commitf1848a4b3f807d21415c5a334b461d240b2a83af (patch)
tree9ab6c3a2da4518cdc8a06893890ea0ca8c174c42 /Zend/zend_API.c
parent4d8541debbc4f2387879a872b42604ed8b908f58 (diff)
downloadphp-git-f1848a4b3f807d21415c5a334b461d240b2a83af.tar.gz
Fix bug #78226: Don't call __set() on uninitialized typed properties
Assigning to an uninitialized typed property will no longer trigger a call to __set(). However, calls to __set() are still triggered if the property is explicitly unset(). This gives us both the behavior people generally expect, and still allows ORMs to do lazy initialization by unsetting properties. For PHP 8, we should fine a way to forbid unsetting of declared properties entirely, and provide a different way to achieve lazy initialization.
Diffstat (limited to 'Zend/zend_API.c')
-rw-r--r--Zend/zend_API.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/Zend/zend_API.c b/Zend/zend_API.c
index 8fab994297..6d9d10a13f 100644
--- a/Zend/zend_API.c
+++ b/Zend/zend_API.c
@@ -1263,13 +1263,13 @@ static zend_always_inline void _object_properties_init(zend_object *object, zend
if (UNEXPECTED(class_type->type == ZEND_INTERNAL_CLASS)) {
do {
- ZVAL_COPY_OR_DUP(dst, src);
+ ZVAL_COPY_OR_DUP_PROP(dst, src);
src++;
dst++;
} while (src != end);
} else {
do {
- ZVAL_COPY(dst, src);
+ ZVAL_COPY_PROP(dst, src);
src++;
dst++;
} while (src != end);
@@ -3725,6 +3725,7 @@ ZEND_API int zend_declare_typed_property(zend_class_entry *ce, zend_string *name
}
}
} else {
+ zval *property_default_ptr;
if ((property_info_ptr = zend_hash_find_ptr(&ce->properties_info, name)) != NULL &&
(property_info_ptr->flags & ZEND_ACC_STATIC) == 0) {
property_info->offset = property_info_ptr->offset;
@@ -3745,7 +3746,9 @@ ZEND_API int zend_declare_typed_property(zend_class_entry *ce, zend_string *name
ce->properties_info_table[ce->default_properties_count - 1] = property_info;
}
}
- ZVAL_COPY_VALUE(&ce->default_properties_table[OBJ_PROP_TO_NUM(property_info->offset)], property);
+ property_default_ptr = &ce->default_properties_table[OBJ_PROP_TO_NUM(property_info->offset)];
+ ZVAL_COPY_VALUE(property_default_ptr, property);
+ Z_PROP_FLAG_P(property_default_ptr) = Z_ISUNDEF_P(property) ? IS_PROP_UNINIT : 0;
}
if (ce->type & ZEND_INTERNAL_CLASS) {
switch(Z_TYPE_P(property)) {