@@ -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-
820783static 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