Skip to content

Commit fe9560a

Browse files
committed
Re-inline the logic for checking a class name in zend_check_type_slow
1 parent 5d77206 commit fe9560a

File tree

1 file changed

+35
-45
lines changed

1 file changed

+35
-45
lines changed

Zend/zend_execute.c

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

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

836826
const uint32_t type_mask = ZEND_TYPE_FULL_MASK(*type);

0 commit comments

Comments
 (0)