diff --git a/NEWS b/NEWS index 1171faacfcb9..b31e07efeb06 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? ????, PHP 8.5.0beta1 +- Core: + . Fixed bug GH-19153 (#[\Attribute] validation should error on + trait/interface/enum/abstract class). (DanielEScherzer) 31 Jul 2025, PHP 8.5.0alpha4 diff --git a/Zend/tests/attributes/Attribute/Attribute_on_abstract.phpt b/Zend/tests/attributes/Attribute/Attribute_on_abstract.phpt new file mode 100644 index 000000000000..547946c4e130 --- /dev/null +++ b/Zend/tests/attributes/Attribute/Attribute_on_abstract.phpt @@ -0,0 +1,12 @@ +--TEST-- +#[Attribute] on an abstract class +--FILE-- + +--EXPECTF-- +Fatal error: Cannot apply #[\Attribute] to abstract class Demo in %s on line %d diff --git a/Zend/tests/attributes/Attribute/Attribute_on_enum.phpt b/Zend/tests/attributes/Attribute/Attribute_on_enum.phpt new file mode 100644 index 000000000000..c5545054dcff --- /dev/null +++ b/Zend/tests/attributes/Attribute/Attribute_on_enum.phpt @@ -0,0 +1,12 @@ +--TEST-- +#[Attribute] on an enum +--FILE-- + +--EXPECTF-- +Fatal error: Cannot apply #[\Attribute] to enum Demo in %s on line %d diff --git a/Zend/tests/attributes/Attribute/Attribute_on_interface.phpt b/Zend/tests/attributes/Attribute/Attribute_on_interface.phpt new file mode 100644 index 000000000000..4b9a87a2395d --- /dev/null +++ b/Zend/tests/attributes/Attribute/Attribute_on_interface.phpt @@ -0,0 +1,12 @@ +--TEST-- +#[Attribute] on an interface +--FILE-- + +--EXPECTF-- +Fatal error: Cannot apply #[\Attribute] to interface Demo in %s on line %d diff --git a/Zend/tests/attributes/Attribute/Attribute_on_trait.phpt b/Zend/tests/attributes/Attribute/Attribute_on_trait.phpt new file mode 100644 index 000000000000..7ea05543baa2 --- /dev/null +++ b/Zend/tests/attributes/Attribute/Attribute_on_trait.phpt @@ -0,0 +1,12 @@ +--TEST-- +#[Attribute] on a trait +--FILE-- + +--EXPECTF-- +Fatal error: Cannot apply #[\Attribute] to trait Demo in %s on line %d diff --git a/Zend/zend_attributes.c b/Zend/zend_attributes.c index 01b16d7d205e..3256e220d8f3 100644 --- a/Zend/zend_attributes.c +++ b/Zend/zend_attributes.c @@ -95,6 +95,24 @@ static void validate_allow_dynamic_properties( scope->ce_flags |= ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES; } +static void validate_attribute( + zend_attribute *attr, uint32_t target, zend_class_entry *scope) +{ + const char *msg = NULL; + if (scope->ce_flags & ZEND_ACC_TRAIT) { + msg = "Cannot apply #[\\Attribute] to trait %s"; + } else if (scope->ce_flags & ZEND_ACC_INTERFACE) { + msg = "Cannot apply #[\\Attribute] to interface %s"; + } else if (scope->ce_flags & ZEND_ACC_ENUM) { + msg = "Cannot apply #[\\Attribute] to enum %s"; + } else if (scope->ce_flags & ZEND_ACC_EXPLICIT_ABSTRACT_CLASS) { + msg = "Cannot apply #[\\Attribute] to abstract class %s"; + } + if (msg != NULL) { + zend_error_noreturn(E_ERROR, msg, ZSTR_VAL(scope->name)); + } +} + ZEND_METHOD(Attribute, __construct) { zend_long flags = ZEND_ATTRIBUTE_TARGET_ALL; @@ -522,6 +540,7 @@ void zend_register_attribute_ce(void) zend_ce_attribute = register_class_Attribute(); attr = zend_mark_internal_attribute(zend_ce_attribute); + attr->validator = validate_attribute; zend_ce_return_type_will_change_attribute = register_class_ReturnTypeWillChange(); zend_mark_internal_attribute(zend_ce_return_type_will_change_attribute);