@@ -186,6 +186,8 @@ class MetadataReader {
186
186
using StoredSize = typename Runtime::StoredSize;
187
187
using TargetClassMetadata = TargetClassMetadataType<Runtime>;
188
188
189
+ static const int defaultTypeRecursionLimit = 50 ;
190
+
189
191
private:
190
192
// / The maximum number of bytes to read when reading metadata. Anything larger
191
193
// / will automatically return failure. This prevents us from reading absurd
@@ -817,12 +819,25 @@ class MetadataReader {
817
819
}
818
820
819
821
// / Given a remote pointer to metadata, attempt to turn it into a type.
820
- BuiltType readTypeFromMetadata (StoredPointer MetadataAddress,
821
- bool skipArtificialSubclasses = false ) {
822
+ BuiltType
823
+ readTypeFromMetadata (StoredPointer MetadataAddress,
824
+ bool skipArtificialSubclasses = false ,
825
+ int recursion_limit = defaultTypeRecursionLimit) {
822
826
auto Cached = TypeCache.find (MetadataAddress);
823
827
if (Cached != TypeCache.end ())
824
828
return Cached->second ;
825
829
830
+ if (recursion_limit <= 0 ) {
831
+ return nullptr ;
832
+ }
833
+
834
+ // readTypeFromMetadata calls out to various other functions which can call
835
+ // back to readTypeFromMetadata. We only want to bump the recursion limit
836
+ // down here, not in the other functions, so that we're only counting
837
+ // recursive calls to readTypeFromMetadata. This decrement is the only place
838
+ // where we'll subtract 1.
839
+ recursion_limit--;
840
+
826
841
// If we see garbage data in the process of building a BuiltType, and get
827
842
// the same metadata address again, we will hit an infinite loop.
828
843
// Insert a negative result into the cache now so that, if we recur with
@@ -835,11 +850,12 @@ class MetadataReader {
835
850
836
851
switch (Meta->getKind ()) {
837
852
case MetadataKind::Class:
838
- return readNominalTypeFromClassMetadata (Meta, skipArtificialSubclasses);
853
+ return readNominalTypeFromClassMetadata (Meta, recursion_limit,
854
+ skipArtificialSubclasses);
839
855
case MetadataKind::Struct:
840
856
case MetadataKind::Enum:
841
857
case MetadataKind::Optional:
842
- return readNominalTypeFromMetadata (Meta);
858
+ return readNominalTypeFromMetadata (Meta, recursion_limit );
843
859
case MetadataKind::Tuple: {
844
860
auto tupleMeta = cast<TargetTupleTypeMetadata<Runtime>>(Meta);
845
861
@@ -848,7 +864,8 @@ class MetadataReader {
848
864
849
865
for (unsigned i = 0 , n = tupleMeta->NumElements ; i != n; ++i) {
850
866
auto &element = tupleMeta->getElement (i);
851
- if (auto elementType = readTypeFromMetadata (element.Type ))
867
+ if (auto elementType =
868
+ readTypeFromMetadata (element.Type , false , recursion_limit))
852
869
elementTypes.push_back (elementType);
853
870
else
854
871
return BuiltType ();
@@ -870,7 +887,8 @@ class MetadataReader {
870
887
871
888
std::vector<FunctionParam<BuiltType>> Parameters;
872
889
for (unsigned i = 0 , n = Function->getNumParameters (); i != n; ++i) {
873
- auto ParamTypeRef = readTypeFromMetadata (Function->getParameter (i));
890
+ auto ParamTypeRef = readTypeFromMetadata (Function->getParameter (i),
891
+ false , recursion_limit);
874
892
if (!ParamTypeRef)
875
893
return BuiltType ();
876
894
@@ -880,7 +898,8 @@ class MetadataReader {
880
898
Parameters.push_back (std::move (Param));
881
899
}
882
900
883
- auto Result = readTypeFromMetadata (Function->ResultType );
901
+ auto Result =
902
+ readTypeFromMetadata (Function->ResultType , false , recursion_limit);
884
903
if (!Result)
885
904
return BuiltType ();
886
905
@@ -894,7 +913,8 @@ class MetadataReader {
894
913
895
914
BuiltType globalActor = BuiltType ();
896
915
if (Function->hasGlobalActor ()) {
897
- globalActor = readTypeFromMetadata (Function->getGlobalActor ());
916
+ globalActor = readTypeFromMetadata (Function->getGlobalActor (), false ,
917
+ recursion_limit);
898
918
if (globalActor)
899
919
flags = flags.withGlobalActor (true );
900
920
}
@@ -929,7 +949,8 @@ class MetadataReader {
929
949
BuiltType SuperclassType = BuiltType ();
930
950
if (Exist->Flags .hasSuperclassConstraint ()) {
931
951
// The superclass is stored after the list of protocols.
932
- SuperclassType = readTypeFromMetadata (Exist->getSuperclassConstraint ());
952
+ SuperclassType = readTypeFromMetadata (Exist->getSuperclassConstraint (),
953
+ false , recursion_limit);
933
954
if (!SuperclassType) return BuiltType ();
934
955
935
956
HasExplicitAnyObject = true ;
@@ -985,7 +1006,7 @@ class MetadataReader {
985
1006
std::vector<BuiltType> builtArgs;
986
1007
for (unsigned i = 0 ; i < shapeArgumentCount; ++i) {
987
1008
auto remoteArg = Exist->getGeneralizationArguments ()[i];
988
- auto builtArg = readTypeFromMetadata (remoteArg);
1009
+ auto builtArg = readTypeFromMetadata (remoteArg, false , recursion_limit );
989
1010
if (!builtArg)
990
1011
return BuiltType ();
991
1012
builtArgs.push_back (builtArg);
@@ -1050,7 +1071,8 @@ class MetadataReader {
1050
1071
1051
1072
case MetadataKind::Metatype: {
1052
1073
auto Metatype = cast<TargetMetatypeMetadata<Runtime>>(Meta);
1053
- auto Instance = readTypeFromMetadata (Metatype->InstanceType );
1074
+ auto Instance =
1075
+ readTypeFromMetadata (Metatype->InstanceType , false , recursion_limit);
1054
1076
if (!Instance) return BuiltType ();
1055
1077
auto BuiltMetatype = Builder.createMetatypeType (Instance);
1056
1078
TypeCache[MetadataAddress] = BuiltMetatype;
@@ -1070,7 +1092,8 @@ class MetadataReader {
1070
1092
}
1071
1093
case MetadataKind::ExistentialMetatype: {
1072
1094
auto Exist = cast<TargetExistentialMetatypeMetadata<Runtime>>(Meta);
1073
- auto Instance = readTypeFromMetadata (Exist->InstanceType );
1095
+ auto Instance =
1096
+ readTypeFromMetadata (Exist->InstanceType , false , recursion_limit);
1074
1097
if (!Instance) return BuiltType ();
1075
1098
auto BuiltExist = Builder.createExistentialMetatypeType (Instance);
1076
1099
TypeCache[MetadataAddress] = BuiltExist;
@@ -2959,8 +2982,9 @@ class MetadataReader {
2959
2982
// TODO: We need to be able to produce protocol conformances for each
2960
2983
// substitution type as well in order to accurately rebuild bound generic
2961
2984
// types or types in protocol-constrained inner contexts.
2962
- std::vector<BuiltType>
2963
- getGenericSubst (MetadataRef metadata, ContextDescriptorRef descriptor) {
2985
+ std::vector<BuiltType> getGenericSubst (MetadataRef metadata,
2986
+ ContextDescriptorRef descriptor,
2987
+ int recursion_limit) {
2964
2988
auto generics = descriptor->getGenericContext ();
2965
2989
if (!generics)
2966
2990
return {};
@@ -2997,8 +3021,8 @@ class MetadataReader {
2997
3021
return {};
2998
3022
}
2999
3023
genericArgsAddr += sizeof (StoredPointer);
3000
-
3001
- auto builtArg = readTypeFromMetadata (arg);
3024
+
3025
+ auto builtArg = readTypeFromMetadata (arg, false , recursion_limit );
3002
3026
if (!builtArg)
3003
3027
return {};
3004
3028
builtSubsts.push_back (builtArg);
@@ -3018,8 +3042,10 @@ class MetadataReader {
3018
3042
return builtSubsts;
3019
3043
}
3020
3044
3021
- BuiltType readNominalTypeFromMetadata (MetadataRef origMetadata,
3022
- bool skipArtificialSubclasses = false ) {
3045
+ BuiltType
3046
+ readNominalTypeFromMetadata (MetadataRef origMetadata,
3047
+ int recursion_limit = defaultTypeRecursionLimit,
3048
+ bool skipArtificialSubclasses = false ) {
3023
3049
auto metadata = origMetadata;
3024
3050
auto descriptorAddress =
3025
3051
readAddressOfNominalTypeDescriptor (metadata,
@@ -3049,7 +3075,8 @@ class MetadataReader {
3049
3075
BuiltType nominal;
3050
3076
if (descriptor->isGeneric ()) {
3051
3077
// Resolve the generic arguments.
3052
- auto builtGenerics = getGenericSubst (metadata, descriptor);
3078
+ auto builtGenerics =
3079
+ getGenericSubst (metadata, descriptor, recursion_limit);
3053
3080
if (builtGenerics.empty ())
3054
3081
return BuiltType ();
3055
3082
nominal = Builder.createBoundGenericType (typeDecl, builtGenerics);
@@ -3071,11 +3098,14 @@ class MetadataReader {
3071
3098
return nominal;
3072
3099
}
3073
3100
3074
- BuiltType readNominalTypeFromClassMetadata (MetadataRef origMetadata,
3075
- bool skipArtificialSubclasses = false ) {
3101
+ BuiltType
3102
+ readNominalTypeFromClassMetadata (MetadataRef origMetadata,
3103
+ int recursion_limit,
3104
+ bool skipArtificialSubclasses = false ) {
3076
3105
auto classMeta = cast<TargetClassMetadata>(origMetadata);
3077
3106
if (classMeta->isTypeMetadata ())
3078
- return readNominalTypeFromMetadata (origMetadata, skipArtificialSubclasses);
3107
+ return readNominalTypeFromMetadata (origMetadata, recursion_limit,
3108
+ skipArtificialSubclasses);
3079
3109
3080
3110
std::string className;
3081
3111
auto origMetadataPtr = getAddress (origMetadata);
@@ -3088,8 +3118,9 @@ class MetadataReader {
3088
3118
if (!stripSignedPointer (classMeta->Superclass ))
3089
3119
return BuiltType ();
3090
3120
3091
- BuiltObjCClass = readTypeFromMetadata (
3092
- stripSignedPointer (classMeta->Superclass ), skipArtificialSubclasses);
3121
+ BuiltObjCClass =
3122
+ readTypeFromMetadata (stripSignedPointer (classMeta->Superclass ),
3123
+ skipArtificialSubclasses, recursion_limit);
3093
3124
}
3094
3125
3095
3126
TypeCache[origMetadataPtr] = BuiltObjCClass;
0 commit comments