Skip to content

Commit 1be3448

Browse files
committed
Re-inline the logic for checking a class name in zend_check_type_slow
1 parent 3d3b88c commit 1be3448

1 file changed

Lines changed: 35 additions & 45 deletions

File tree

Zend/zend_execute.c

Lines changed: 35 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -739,9 +739,10 @@ static const zend_class_entry *resolve_single_class_type(
739739
zend_string *name,
740740
const zend_class_entry *scope) {
741741
if (zend_string_equals_ci(name, ZSTR_KNOWN(ZEND_STR_SELF))) {
742+
/* If we don't have a scope, returning the NULL pointer is fine as the error handling is done on the call site */
742743
return scope;
743744
} else if (UNEXPECTED(zend_string_equals_ci(name, ZSTR_KNOWN(ZEND_STR_PARENT)))) { // Parent as a type is extremely uncommon
744-
return scope->parent;
745+
return scope ? scope->parent : NULL;
745746
} else {
746747
return zend_lookup_class_ex(name, NULL, ZEND_FETCH_CLASS_NO_AUTOLOAD | ZEND_FETCH_CLASS_SILENT);
747748
}
@@ -779,57 +780,46 @@ static bool zend_check_intersection_type_from_list(
779780
return true;
780781
}
781782

782-
static bool zend_check_class_type(
783-
const zend_type *type,
784-
const zend_class_entry *arg_ce,
785-
const zend_class_entry *scope
786-
) {
787-
const zend_class_entry *ce;
788-
if (UNEXPECTED(ZEND_TYPE_HAS_LIST(*type))) {
789-
if (ZEND_TYPE_IS_INTERSECTION(*type)) {
790-
return zend_check_intersection_type_from_list(ZEND_TYPE_LIST(*type), arg_ce, scope);
791-
} else {
792-
/* In a union type may be of simple atomic types or a DNF type */
793-
const zend_type *list_type;
794-
ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(*type), list_type) {
795-
if (ZEND_TYPE_IS_INTERSECTION(*list_type)) {
796-
if (zend_check_intersection_type_from_list(ZEND_TYPE_LIST(*list_type), arg_ce, scope)) {
797-
return true;
798-
}
799-
} else {
800-
ZEND_ASSERT(!ZEND_TYPE_HAS_LIST(*list_type));
801-
ce = zend_ce_from_type(list_type, scope);
802-
/* Instance of a single type part of a union is sufficient to pass the type check */
803-
if (ce && instanceof_function(arg_ce, ce)) {
804-
return true;
805-
}
806-
}
807-
} ZEND_TYPE_LIST_FOREACH_END();
808-
}
809-
} else {
810-
ce = zend_ce_from_type(type, scope);
811-
/* If we have a CE we check if it satisfies the type constraint,
812-
* otherwise it will check if a standard type satisfies it. */
813-
if (ce && instanceof_function(arg_ce, ce)) {
814-
return true;
815-
}
816-
}
817-
return false;
818-
}
819-
820783
static zend_type_check_status zend_check_type_slow(
821784
const zend_type *type,
822785
const zval *arg,
823786
const zend_class_entry *scope,
824787
bool strict_types,
825788
const uint32_t callable_check_flag /* This is needed to pass IS_CALLABLE_SUPPRESS_DEPRECATIONS for internal functions */
826789
) {
827-
if (
828-
ZEND_TYPE_IS_COMPLEX(*type)
829-
&& EXPECTED(Z_TYPE_P(arg) == IS_OBJECT)
830-
&& zend_check_class_type(type, Z_OBJCE_P(arg), scope)
831-
) {
832-
return ZEND_TYPE_CHECK_VALID;
790+
if (ZEND_TYPE_IS_COMPLEX(*type) && EXPECTED(Z_TYPE_P(arg) == IS_OBJECT)) {
791+
const zend_class_entry *arg_ce = Z_OBJCE_P(arg);
792+
if (EXPECTED(ZEND_TYPE_HAS_NAME(*type))) {
793+
const zend_class_entry *ce = zend_ce_from_type(type, scope);
794+
/* If we have a CE we check if it satisfies the type constraint,
795+
* otherwise it will check if a standard type satisfies it. */
796+
if (ce && instanceof_function(arg_ce, ce)) {
797+
return ZEND_TYPE_CHECK_VALID;
798+
}
799+
} else {
800+
ZEND_ASSERT(ZEND_TYPE_HAS_LIST(*type));
801+
if (ZEND_TYPE_IS_INTERSECTION(*type)) {
802+
return zend_check_intersection_type_from_list(ZEND_TYPE_LIST(*type), arg_ce, scope)
803+
? ZEND_TYPE_CHECK_VALID : ZEND_TYPE_CHECK_INVALID;
804+
} else {
805+
/* In a union type may be of simple atomic types or a DNF type */
806+
const zend_type *list_type;
807+
ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(*type), list_type) {
808+
if (ZEND_TYPE_IS_INTERSECTION(*list_type)) {
809+
if (zend_check_intersection_type_from_list(ZEND_TYPE_LIST(*list_type), arg_ce, scope)) {
810+
return ZEND_TYPE_CHECK_VALID;
811+
}
812+
} else {
813+
ZEND_ASSERT(!ZEND_TYPE_HAS_LIST(*list_type));
814+
const zend_class_entry *ce = zend_ce_from_type(list_type, scope);
815+
/* Instance of a single type part of a union is sufficient to pass the type check */
816+
if (ce && instanceof_function(arg_ce, ce)) {
817+
return ZEND_TYPE_CHECK_VALID;
818+
}
819+
}
820+
} ZEND_TYPE_LIST_FOREACH_END();
821+
}
822+
}
833823
}
834824

835825
const uint32_t type_mask = ZEND_TYPE_FULL_MASK(*type);

0 commit comments

Comments
 (0)