diff --git a/Zend/tests/gh16725.phpt b/Zend/tests/gh16725.phpt new file mode 100644 index 0000000000000..e9a2564fc0151 --- /dev/null +++ b/Zend/tests/gh16725.phpt @@ -0,0 +1,27 @@ +--TEST-- +GH-16725: Incorrect access check for non-hooked props in hooked object iterator +--FILE-- + 'bar'; } + + public function __construct( + private string $prop2, + ) {} + + public function jsonSerialize(): mixed { + return get_object_vars($this); + } +} + +$obj = new C('foo'); +var_dump(get_object_vars($obj)); +echo json_encode($obj); + +?> +--EXPECT-- +array(0) { +} +{"prop1":"bar","prop2":"foo"} diff --git a/Zend/zend_property_hooks.c b/Zend/zend_property_hooks.c index 0286bc0c4486f..82ddf2f8835a0 100644 --- a/Zend/zend_property_hooks.c +++ b/Zend/zend_property_hooks.c @@ -89,7 +89,8 @@ static zend_array *zho_build_properties_ex(zend_object *zobj, bool check_access, if (UNEXPECTED(Z_TYPE_P(OBJ_PROP(zobj, prop_info->offset)) == IS_UNDEF)) { HT_FLAGS(properties) |= HASH_FLAG_HAS_EMPTY_IND; } - zend_hash_update_ind(properties, property_name, OBJ_PROP(zobj, prop_info->offset)); + zval *tmp = zend_hash_lookup(properties, property_name); + ZVAL_INDIRECT(tmp, OBJ_PROP(zobj, prop_info->offset)); } skip_property: if (property_name != prop_info->name) {