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