]> granicus.if.org Git - php/commitdiff
Preserve original ce_flags when registering class
authorNikita Popov <nikita.ppv@gmail.com>
Mon, 20 Jul 2020 14:56:20 +0000 (16:56 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Mon, 20 Jul 2020 15:00:04 +0000 (17:00 +0200)
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
ext/reflection/tests/ReflectionAttribute_final.phpt [new file with mode: 0644]

index 434a5befc14a21e8da743855f63b6a9e6c29a8f9..7a8816b5cfef53d10ff2ca9d90275a7cdc338468 100644 (file)
@@ -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 (file)
index 0000000..f2899d9
--- /dev/null
@@ -0,0 +1,10 @@
+--TEST--
+Check that ReflectionAttribute is final
+--FILE--
+<?php
+
+class T extends ReflectionAttribute {}
+
+?>
+--EXPECTF--
+Fatal error: Class T may not inherit from final class (ReflectionAttribute) in %s on line %d