diff --git a/NEWS b/NEWS index bfef897a3fc..961ce989da4 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,7 @@ PHP NEWS - Core: . Fixed bug GH-15330 (Do not scan generator frames more than once). (Arnaud) + . Fixed bug GH-15644 (Asymmetric visibility doesn't work with hooks). (ilutov) - DOM: . Fixed bug GH-13988 (Storing DOMElement consume 4 times more memory in diff --git a/Zend/tests/property_hooks/gh15644.phpt b/Zend/tests/property_hooks/gh15644.phpt new file mode 100644 index 00000000000..1e0dda3a0e4 --- /dev/null +++ b/Zend/tests/property_hooks/gh15644.phpt @@ -0,0 +1,32 @@ +--TEST-- +GH-15644: Asymmetric visibility doesn't work for set hook +--FILE-- + $value; + } + public private(set) string $prop2 { + get => $this->prop2; + } +} + +$c = new C(); + +try { + $c->prop1 = 'hello world'; +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +try { + $c->prop2 = 'hello world'; +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +?> +--EXPECT-- +Cannot modify private(set) property C::$prop1 from global scope +Cannot modify private(set) property C::$prop2 from global scope diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index fdac24ccb25..65f8ce4b052 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -1057,6 +1057,14 @@ found:; } goto try_again; } + + if (UNEXPECTED(prop_info->flags & ZEND_ACC_PPP_SET_MASK + && !zend_asymmetric_property_has_set_access(prop_info))) { + zend_asymmetric_visibility_property_modification_error(prop_info, "modify"); + variable_ptr = &EG(error_zval); + goto exit; + } + GC_ADDREF(zobj); zend_call_known_instance_method_with_1_params(set, zobj, NULL, value); OBJ_RELEASE(zobj);