From 236ddc56a28e9f482f0d3b3ae3ef683de79440e9 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 20 Jul 2020 16:56:20 +0200 Subject: [PATCH] Preserve original ce_flags when registering class Bug that regularly sneaks in: ZEND_ACC_FINAL is set before calling zend_register_internal_class() and promptly gets ignored. Remove this footgun by preserving flags from the original CE. --- Zend/zend_API.c | 2 +- ext/reflection/tests/ReflectionAttribute_final.phpt | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 ext/reflection/tests/ReflectionAttribute_final.phpt diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 434a5befc1..7a8816b5cf 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -2577,7 +2577,7 @@ static zend_class_entry *do_register_internal_class(zend_class_entry *orig_class class_entry->type = ZEND_INTERNAL_CLASS; zend_initialize_class_data(class_entry, 0); - class_entry->ce_flags = ce_flags | ZEND_ACC_CONSTANTS_UPDATED | ZEND_ACC_LINKED | ZEND_ACC_RESOLVED_PARENT | ZEND_ACC_RESOLVED_INTERFACES; + class_entry->ce_flags = orig_class_entry->ce_flags | ce_flags | ZEND_ACC_CONSTANTS_UPDATED | ZEND_ACC_LINKED | ZEND_ACC_RESOLVED_PARENT | ZEND_ACC_RESOLVED_INTERFACES; class_entry->info.internal.module = EG(current_module); if (class_entry->info.internal.builtin_functions) { diff --git a/ext/reflection/tests/ReflectionAttribute_final.phpt b/ext/reflection/tests/ReflectionAttribute_final.phpt new file mode 100644 index 0000000000..f2899d9724 --- /dev/null +++ b/ext/reflection/tests/ReflectionAttribute_final.phpt @@ -0,0 +1,10 @@ +--TEST-- +Check that ReflectionAttribute is final +--FILE-- + +--EXPECTF-- +Fatal error: Class T may not inherit from final class (ReflectionAttribute) in %s on line %d -- 2.50.1