URL: http://github.com/php/php-src/pull/21998.patch
4582756b2 --- /dev/null +++ b/Zend/tests/attributes/deprecated/interfaces/inherited_interface_implementation.phpt @@ -0,0 +1,15 @@ +--TEST-- +#[\Deprecated]: Parent class implements deprecated interface, child class inherits +--FILE-- + +--EXPECTF-- +Deprecated: Interface DemoInterface implemented by Base is deprecated, please do not use in %s on line %d diff --git a/Zend/tests/attributes/deprecated/interfaces/inherited_manual_interface_implementation.phpt b/Zend/tests/attributes/deprecated/interfaces/inherited_manual_interface_implementation.phpt new file mode 100644 index 000000000000..b7540175e69e --- /dev/null +++ b/Zend/tests/attributes/deprecated/interfaces/inherited_manual_interface_implementation.phpt @@ -0,0 +1,17 @@ +--TEST-- +#[\Deprecated]: Parent class implements deprecated interface, child class inherits and also implements +--FILE-- + +--EXPECTF-- +Deprecated: Interface DemoInterface implemented by Base is deprecated, please do not use in %s on line %d + +Deprecated: Interface DemoInterface implemented by Child is deprecated, please do not use in %s on line %d diff --git a/Zend/tests/attributes/deprecated/interfaces/throwing_error_handler.phpt b/Zend/tests/attributes/deprecated/interfaces/throwing_error_handler.phpt new file mode 100644 index 000000000000..75c0af92abe8 --- /dev/null +++ b/Zend/tests/attributes/deprecated/interfaces/throwing_error_handler.phpt @@ -0,0 +1,23 @@ +--TEST-- +#[\Deprecated]: Deprecation converted to ErrorException does not break +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught ErrorException: Interface DemoInterface implemented by DemoClass is deprecated in %s:%d +Stack trace: +#0 %s(%d): my_error_handler(16384, 'Interface DemoI...', '/usr/src/php/Ze...', 12) +#1 {main} + thrown in %s on line %d diff --git a/Zend/tests/attributes/deprecated/interfaces/type_okay.phpt b/Zend/tests/attributes/deprecated/interfaces/type_okay.phpt new file mode 100644 index 000000000000..d9e558ff63c2 --- /dev/null +++ b/Zend/tests/attributes/deprecated/interfaces/type_okay.phpt @@ -0,0 +1,35 @@ +--TEST-- +#[\Deprecated]: Instanceof, type checking, etc. for deprecated interfaces are okay +--FILE-- + +--EXPECTF-- +Deprecated: Interface DemoInterface implemented by ImplementsDemo is deprecated, please do not use in %s on line %d +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) diff --git a/Zend/zend_attributes.c b/Zend/zend_attributes.c index 71f0d788e921..67b313984cfc 100644 --- a/Zend/zend_attributes.c +++ b/Zend/zend_attributes.c @@ -118,7 +118,7 @@ static zend_string *validate_deprecated( /* Being used for a method or something, validation does not apply */ return NULL; } - if (!(scope->ce_flags & ZEND_ACC_TRAIT)) { + if (!(scope->ce_flags & (ZEND_ACC_TRAIT|ZEND_ACC_INTERFACE))) { const char *type = zend_get_object_type_case(scope, false); return zend_strpprintf(0, "Cannot apply #[\\Deprecated] to %s %s", type, ZSTR_VAL(scope->name)); } diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 4253037fda52..c3b476efd632 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -2032,6 +2032,43 @@ ZEND_API ZEND_COLD void zend_use_of_deprecated_trait( zend_string_release(message_suffix); } +static ZEND_COLD void zend_deprecated_interface_action( + zend_class_entry *interface, + const zend_string *by, + const char *action +) { + zend_string *message_suffix = ZSTR_EMPTY_ALLOC(); + + if (get_deprecation_suffix_from_attribute(interface->attributes, interface, &message_suffix) == FAILURE) { + return; + } + + int code = interface->type == ZEND_INTERNAL_CLASS ? E_DEPRECATED : E_USER_DEPRECATED; + + zend_error_unchecked(code, "Interface %s %s by %s is deprecated%S", + ZSTR_VAL(interface->name), + action, + ZSTR_VAL(by), + message_suffix + ); + + zend_string_release(message_suffix); +} + +ZEND_API ZEND_COLD void zend_implementation_of_deprecated_interface( + zend_class_entry *interface, + const zend_string *implemented_by +) { + zend_deprecated_interface_action(interface, implemented_by, "implemented"); +} + +ZEND_API ZEND_COLD void zend_extending_deprecated_interface( + zend_class_entry *interface, + const zend_string *extended_by +) { + zend_deprecated_interface_action(interface, extended_by, "extended"); +} + ZEND_API ZEND_COLD void ZEND_FASTCALL zend_false_to_array_deprecated(void) { zend_error(E_DEPRECATED, "Automatic conversion of false to array is deprecated"); diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h index ba48b19bcfe1..39f4f2e64509 100644 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@ -66,6 +66,8 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_nodiscard_function(const zend_functio ZEND_API ZEND_COLD void ZEND_FASTCALL zend_deprecated_class_constant(const zend_class_constant *c, const zend_string *constant_name); ZEND_API ZEND_COLD void ZEND_FASTCALL zend_deprecated_constant(const zend_constant *c, const zend_string *constant_name); ZEND_API ZEND_COLD void zend_use_of_deprecated_trait(zend_class_entry *trait, const zend_string *used_by); +ZEND_API ZEND_COLD void zend_implementation_of_deprecated_interface(zend_class_entry *interface, const zend_string *implemented_by); +ZEND_API ZEND_COLD void zend_extending_deprecated_interface(zend_class_entry *interface, const zend_string *extended_by); ZEND_API ZEND_COLD void ZEND_FASTCALL zend_false_to_array_deprecated(void); ZEND_COLD void ZEND_FASTCALL zend_param_must_be_ref(const zend_function *func, uint32_t arg_num); ZEND_API ZEND_COLD void ZEND_FASTCALL zend_use_resource_as_offset(const zval *dim); diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index d70d08f5f1c4..7ed3ccc41fc3 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -3557,6 +3557,17 @@ ZEND_API zend_class_entry *zend_do_link_class(zend_class_entry *ce, zend_string free_alloca(traits_and_interfaces, use_heap); return NULL; } + if (UNEXPECTED(iface->ce_flags & ZEND_ACC_DEPRECATED)) { + if (ce->ce_flags & ZEND_ACC_INTERFACE) { + zend_extending_deprecated_interface(iface, ce->name); + } else { + zend_implementation_of_deprecated_interface(iface, ce->name); + } + if (UNEXPECTED(EG(exception))) { + free_alloca(traits_and_interfaces, use_heap); + return NULL; + } + } traits_and_interfaces[ce->num_traits + i] = iface; if (iface) { UPDATE_IS_CACHEABLE(iface); From 99348433712396ae47efe2f3eaf13906866fd67f Mon Sep 17 00:00:00 2001 From: Daniel ScherzerNote: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: