@@ -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
@@ -803,12 +805,25 @@ class MetadataReader {
803
805
}
804
806
805
807
// / Given a remote pointer to metadata, attempt to turn it into a type.
806
- BuiltType readTypeFromMetadata (StoredPointer MetadataAddress,
807
- bool skipArtificialSubclasses = false ) {
808
+ BuiltType
809
+ readTypeFromMetadata (StoredPointer MetadataAddress,
810
+ bool skipArtificialSubclasses = false ,
811
+ int recursion_limit = defaultTypeRecursionLimit) {
808
812
auto Cached = TypeCache.find (MetadataAddress);
809
813
if (Cached != TypeCache.end ())
810
814
return Cached->second ;
811
815
816
+ if (recursion_limit <= 0 ) {
817
+ return nullptr ;
818
+ }
819
+
820
+ // readTypeFromMetadata calls out to various other functions which can call
821
+ // back to readTypeFromMetadata. We only want to bump the recursion limit
822
+ // down here, not in the other functions, so that we're only counting
823
+ // recursive calls to readTypeFromMetadata. This decrement is the only place
824
+ // where we'll subtract 1.
825
+ recursion_limit--;
826
+
812
827
// If we see garbage data in the process of building a BuiltType, and get
813
828
// the same metadata address again, we will hit an infinite loop.
814
829
// Insert a negative result into the cache now so that, if we recur with
@@ -821,11 +836,12 @@ class MetadataReader {
821
836
822
837
switch (Meta->getKind ()) {
823
838
case MetadataKind::Class:
824
- return readNominalTypeFromClassMetadata (Meta, skipArtificialSubclasses);
839
+ return readNominalTypeFromClassMetadata (Meta, recursion_limit,
840
+ skipArtificialSubclasses);
825
841
case MetadataKind::Struct:
826
842
case MetadataKind::Enum:
827
843
case MetadataKind::Optional:
828
- return readNominalTypeFromMetadata (Meta);
844
+ return readNominalTypeFromMetadata (Meta, recursion_limit );
829
845
case MetadataKind::Tuple: {
830
846
auto tupleMeta = cast<TargetTupleTypeMetadata<Runtime>>(Meta);
831
847
@@ -834,7 +850,8 @@ class MetadataReader {
834
850
835
851
for (unsigned i = 0 , n = tupleMeta->NumElements ; i != n; ++i) {
836
852
auto &element = tupleMeta->getElement (i);
837
- if (auto elementType = readTypeFromMetadata (element.Type ))
853
+ if (auto elementType =
854
+ readTypeFromMetadata (element.Type , false , recursion_limit))
838
855
elementTypes.push_back (elementType);
839
856
else
840
857
return BuiltType ();
@@ -856,7 +873,8 @@ class MetadataReader {
856
873
857
874
std::vector<FunctionParam<BuiltType>> Parameters;
858
875
for (unsigned i = 0 , n = Function->getNumParameters (); i != n; ++i) {
859
- auto ParamTypeRef = readTypeFromMetadata (Function->getParameter (i));
876
+ auto ParamTypeRef = readTypeFromMetadata (Function->getParameter (i),
877
+ false , recursion_limit);
860
878
if (!ParamTypeRef)
861
879
return BuiltType ();
862
880
@@ -866,7 +884,8 @@ class MetadataReader {
866
884
Parameters.push_back (std::move (Param));
867
885
}
868
886
869
- auto Result = readTypeFromMetadata (Function->ResultType );
887
+ auto Result =
888
+ readTypeFromMetadata (Function->ResultType , false , recursion_limit);
870
889
if (!Result)
871
890
return BuiltType ();
872
891
@@ -880,7 +899,8 @@ class MetadataReader {
880
899
881
900
BuiltType globalActor = BuiltType ();
882
901
if (Function->hasGlobalActor ()) {
883
- globalActor = readTypeFromMetadata (Function->getGlobalActor ());
902
+ globalActor = readTypeFromMetadata (Function->getGlobalActor (), false ,
903
+ recursion_limit);
884
904
if (globalActor)
885
905
flags = flags.withGlobalActor (true );
886
906
}
@@ -915,7 +935,8 @@ class MetadataReader {
915
935
BuiltType SuperclassType = BuiltType ();
916
936
if (Exist->Flags .hasSuperclassConstraint ()) {
917
937
// The superclass is stored after the list of protocols.
918
- SuperclassType = readTypeFromMetadata (Exist->getSuperclassConstraint ());
938
+ SuperclassType = readTypeFromMetadata (Exist->getSuperclassConstraint (),
939
+ false , recursion_limit);
919
940
if (!SuperclassType) return BuiltType ();
920
941
921
942
HasExplicitAnyObject = true ;
@@ -971,7 +992,7 @@ class MetadataReader {
971
992
std::vector<BuiltType> builtArgs;
972
993
for (unsigned i = 0 ; i < shapeArgumentCount; ++i) {
973
994
auto remoteArg = Exist->getGeneralizationArguments ()[i];
974
- auto builtArg = readTypeFromMetadata (remoteArg);
995
+ auto builtArg = readTypeFromMetadata (remoteArg, false , recursion_limit );
975
996
if (!builtArg)
976
997
return BuiltType ();
977
998
builtArgs.push_back (builtArg);
@@ -1036,7 +1057,8 @@ class MetadataReader {
1036
1057
1037
1058
case MetadataKind::Metatype: {
1038
1059
auto Metatype = cast<TargetMetatypeMetadata<Runtime>>(Meta);
1039
- auto Instance = readTypeFromMetadata (Metatype->InstanceType );
1060
+ auto Instance =
1061
+ readTypeFromMetadata (Metatype->InstanceType , false , recursion_limit);
1040
1062
if (!Instance) return BuiltType ();
1041
1063
auto BuiltMetatype = Builder.createMetatypeType (Instance);
1042
1064
TypeCache[MetadataAddress] = BuiltMetatype;
@@ -1056,7 +1078,8 @@ class MetadataReader {
1056
1078
}
1057
1079
case MetadataKind::ExistentialMetatype: {
1058
1080
auto Exist = cast<TargetExistentialMetatypeMetadata<Runtime>>(Meta);
1059
- auto Instance = readTypeFromMetadata (Exist->InstanceType );
1081
+ auto Instance =
1082
+ readTypeFromMetadata (Exist->InstanceType , false , recursion_limit);
1060
1083
if (!Instance) return BuiltType ();
1061
1084
auto BuiltExist = Builder.createExistentialMetatypeType (Instance);
1062
1085
TypeCache[MetadataAddress] = BuiltExist;
@@ -2948,8 +2971,9 @@ class MetadataReader {
2948
2971
// TODO: We need to be able to produce protocol conformances for each
2949
2972
// substitution type as well in order to accurately rebuild bound generic
2950
2973
// types or types in protocol-constrained inner contexts.
2951
- std::vector<BuiltType>
2952
- getGenericSubst (MetadataRef metadata, ContextDescriptorRef descriptor) {
2974
+ std::vector<BuiltType> getGenericSubst (MetadataRef metadata,
2975
+ ContextDescriptorRef descriptor,
2976
+ int recursion_limit) {
2953
2977
auto generics = descriptor->getGenericContext ();
2954
2978
if (!generics)
2955
2979
return {};
@@ -2986,8 +3010,8 @@ class MetadataReader {
2986
3010
return {};
2987
3011
}
2988
3012
genericArgsAddr += sizeof (StoredPointer);
2989
-
2990
- auto builtArg = readTypeFromMetadata (arg);
3013
+
3014
+ auto builtArg = readTypeFromMetadata (arg, false , recursion_limit );
2991
3015
if (!builtArg)
2992
3016
return {};
2993
3017
builtSubsts.push_back (builtArg);
@@ -3007,8 +3031,10 @@ class MetadataReader {
3007
3031
return builtSubsts;
3008
3032
}
3009
3033
3010
- BuiltType readNominalTypeFromMetadata (MetadataRef origMetadata,
3011
- bool skipArtificialSubclasses = false ) {
3034
+ BuiltType
3035
+ readNominalTypeFromMetadata (MetadataRef origMetadata,
3036
+ int recursion_limit = defaultTypeRecursionLimit,
3037
+ bool skipArtificialSubclasses = false ) {
3012
3038
auto metadata = origMetadata;
3013
3039
auto descriptorAddress =
3014
3040
readAddressOfNominalTypeDescriptor (metadata,
@@ -3038,7 +3064,8 @@ class MetadataReader {
3038
3064
BuiltType nominal;
3039
3065
if (descriptor->isGeneric ()) {
3040
3066
// Resolve the generic arguments.
3041
- auto builtGenerics = getGenericSubst (metadata, descriptor);
3067
+ auto builtGenerics =
3068
+ getGenericSubst (metadata, descriptor, recursion_limit);
3042
3069
if (builtGenerics.empty ())
3043
3070
return BuiltType ();
3044
3071
nominal = Builder.createBoundGenericType (typeDecl, builtGenerics);
@@ -3060,11 +3087,14 @@ class MetadataReader {
3060
3087
return nominal;
3061
3088
}
3062
3089
3063
- BuiltType readNominalTypeFromClassMetadata (MetadataRef origMetadata,
3064
- bool skipArtificialSubclasses = false ) {
3090
+ BuiltType
3091
+ readNominalTypeFromClassMetadata (MetadataRef origMetadata,
3092
+ int recursion_limit,
3093
+ bool skipArtificialSubclasses = false ) {
3065
3094
auto classMeta = cast<TargetClassMetadata>(origMetadata);
3066
3095
if (classMeta->isTypeMetadata ())
3067
- return readNominalTypeFromMetadata (origMetadata, skipArtificialSubclasses);
3096
+ return readNominalTypeFromMetadata (origMetadata, recursion_limit,
3097
+ skipArtificialSubclasses);
3068
3098
3069
3099
std::string className;
3070
3100
auto origMetadataPtr = getAddress (origMetadata);
@@ -3077,8 +3107,9 @@ class MetadataReader {
3077
3107
if (!stripSignedPointer (classMeta->Superclass ))
3078
3108
return BuiltType ();
3079
3109
3080
- BuiltObjCClass = readTypeFromMetadata (
3081
- stripSignedPointer (classMeta->Superclass ), skipArtificialSubclasses);
3110
+ BuiltObjCClass =
3111
+ readTypeFromMetadata (stripSignedPointer (classMeta->Superclass ),
3112
+ skipArtificialSubclasses, recursion_limit);
3082
3113
}
3083
3114
3084
3115
TypeCache[origMetadataPtr] = BuiltObjCClass;
0 commit comments