From 0df488e6eaa6a959a33056a7c21e4ec73ae9512a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Fri, 16 Oct 2026 10:53:37 +0200 Subject: [PATCH] Skip the parent-chain walk in instanceof for a final or enum RHS A final class cannot be extended, and an enum is always final, so a final or enum class entry can never be an ancestor of the left hand side. Return false immediately instead of walking the parent chain. Internal enums created by zend_register_internal_enum() only set ZEND_ACC_ENUM, so the check tests both ZEND_ACC_FINAL and ZEND_ACC_ENUM. The interface branch is left untouched, since interfaces can never be final. --- Zend/tests/instanceof_final.phpt | 106 +++++++++++++++++++++++++++++++ Zend/zend_operators.c | 5 ++ 2 files changed, 111 insertions(+) create mode 100644 Zend/tests/instanceof_final.phpt diff --git a/Zend/tests/instanceof_final.phpt b/Zend/tests/instanceof_final.phpt new file mode 100644 index 000000000000..7a0c811436ba --- /dev/null +++ b/Zend/tests/instanceof_final.phpt @@ -0,0 +1,106 @@ +--TEST-- +instanceof against a final class or an enum +--FILE-- +test(); + +?> +--EXPECT-- +bool(true) +bool(false) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(true) +bool(false) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(true) +bool(false) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index 9f1e18b5ca49..8af1097596a6 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -2648,6 +2648,11 @@ ZEND_API bool ZEND_FASTCALL instanceof_function_slow(const zend_class_entry *ins } return 0; } else { + /* A final class cannot be extended, and an enum is always final, so ce + * cannot be an ancestor of instance_ce. */ + if (ce->ce_flags & (ZEND_ACC_FINAL|ZEND_ACC_ENUM)) { + return 0; + } while (1) { instance_ce = instance_ce->parent; if (instance_ce == ce) {