diff --git a/Zend/tests/property_hooks/gh18268.phpt b/Zend/tests/property_hooks/gh18268.phpt new file mode 100644 index 00000000000..9836bb6d962 --- /dev/null +++ b/Zend/tests/property_hooks/gh18268.phpt @@ -0,0 +1,23 @@ +--TEST-- +GH-18268: array_walk() on object with added property hooks +--FILE-- + +--EXPECT-- +int(42) diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index db087bdd600..4f7d158ba0f 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -467,6 +467,8 @@ typedef struct _zend_property_info { ((uint32_t)(XtOffsetOf(zend_object, properties_table) + sizeof(zval) * (num))) #define OBJ_PROP_TO_NUM(offset) \ (((offset) - OBJ_PROP_TO_OFFSET(0)) / sizeof(zval)) +#define OBJ_PROP_SLOT_TO_OFFSET(obj, slot) \ + ((uintptr_t)(slot) - (uintptr_t)(obj)) typedef struct _zend_class_constant { zval value; /* flags are stored in u2 */ diff --git a/Zend/zend_objects_API.c b/Zend/zend_objects_API.c index 1ba250bec64..9b1b6dd4fcb 100644 --- a/Zend/zend_objects_API.c +++ b/Zend/zend_objects_API.c @@ -203,7 +203,7 @@ ZEND_API void ZEND_FASTCALL zend_objects_store_del(zend_object *object) /* {{{ * ZEND_API ZEND_COLD zend_property_info *zend_get_property_info_for_slot_slow(zend_object *obj, zval *slot) { - uintptr_t offset = (uintptr_t)slot - (uintptr_t)obj->properties_table; + uintptr_t offset = OBJ_PROP_SLOT_TO_OFFSET(obj, slot); zend_property_info *prop_info; ZEND_HASH_MAP_FOREACH_PTR(&obj->ce->properties_info, prop_info) { if (prop_info->offset == offset) {