Browse Source

Fix stack overflow in RequiredNamespaceCollector

pull/1198/head
Siegfried Pammer 7 years ago
parent
commit
7298592df7
  1. 30
      ICSharpCode.Decompiler/CSharp/RequiredNamespaceCollector.cs

30
ICSharpCode.Decompiler/CSharp/RequiredNamespaceCollector.cs

@ -26,7 +26,7 @@ namespace ICSharpCode.Decompiler.CSharp
} }
} }
public static void CollectNamespaces(IEntity entity, DecompilerTypeSystem typeSystem, HashSet<string> namespaces) public static void CollectNamespaces(IEntity entity, DecompilerTypeSystem typeSystem, HashSet<string> namespaces, bool scanningFullType = false)
{ {
if (entity == null) if (entity == null)
return; return;
@ -44,23 +44,23 @@ namespace ICSharpCode.Decompiler.CSharp
} }
foreach (var nestedType in td.NestedTypes) { foreach (var nestedType in td.NestedTypes) {
CollectNamespaces(nestedType, typeSystem, namespaces); CollectNamespaces(nestedType, typeSystem, namespaces, scanningFullType: true);
} }
foreach (var field in td.Fields) { foreach (var field in td.Fields) {
CollectNamespaces(field, typeSystem, namespaces); CollectNamespaces(field, typeSystem, namespaces, scanningFullType: true);
} }
foreach (var property in td.Properties) { foreach (var property in td.Properties) {
CollectNamespaces(property, typeSystem, namespaces); CollectNamespaces(property, typeSystem, namespaces, scanningFullType: true);
} }
foreach (var @event in td.Events) { foreach (var @event in td.Events) {
CollectNamespaces(@event, typeSystem, namespaces); CollectNamespaces(@event, typeSystem, namespaces, scanningFullType: true);
} }
foreach (var method in td.Methods) { foreach (var method in td.Methods) {
CollectNamespaces(method, typeSystem, namespaces); CollectNamespaces(method, typeSystem, namespaces, scanningFullType: true);
} }
break; break;
case IField field: case IField field:
@ -81,7 +81,7 @@ namespace ICSharpCode.Decompiler.CSharp
var reader = typeSystem.ModuleDefinition.Reader; var reader = typeSystem.ModuleDefinition.Reader;
var methodDef = typeSystem.ModuleDefinition.Metadata.GetMethodDefinition((MethodDefinitionHandle)method.MetadataToken); var methodDef = typeSystem.ModuleDefinition.Metadata.GetMethodDefinition((MethodDefinitionHandle)method.MetadataToken);
var body = reader.GetMethodBody(methodDef.RelativeVirtualAddress); var body = reader.GetMethodBody(methodDef.RelativeVirtualAddress);
CollectNamespacesFromMethodBody(body, reader, typeSystem, namespaces); CollectNamespacesFromMethodBody(body, reader, typeSystem, namespaces, scanningFullType: scanningFullType);
} }
break; break;
case IProperty property: case IProperty property:
@ -126,7 +126,11 @@ namespace ICSharpCode.Decompiler.CSharp
public static void CollectNamespaces(EntityHandle entity, DecompilerTypeSystem typeSystem, HashSet<string> namespaces) public static void CollectNamespaces(EntityHandle entity, DecompilerTypeSystem typeSystem, HashSet<string> namespaces)
{ {
CollectNamespaces(entity.Kind.IsTypeKind() ? (IEntity)typeSystem.ResolveAsType(entity).GetDefinition() : typeSystem.ResolveAsMember(entity), typeSystem, namespaces); if (entity.Kind.IsTypeKind()) {
CollectNamespaces(typeSystem.ResolveAsType(entity).GetDefinition(), typeSystem, namespaces);
} else {
CollectNamespaces(typeSystem.ResolveAsMember(entity), typeSystem, namespaces);
}
} }
static void HandleAttributes(IEnumerable<IAttribute> attributes, HashSet<string> namespaces) static void HandleAttributes(IEnumerable<IAttribute> attributes, HashSet<string> namespaces)
@ -146,7 +150,7 @@ namespace ICSharpCode.Decompiler.CSharp
} }
} }
static void CollectNamespacesFromMethodBody(MethodBodyBlock method, PEReader reader, DecompilerTypeSystem typeSystem, HashSet<string> namespaces) static void CollectNamespacesFromMethodBody(MethodBodyBlock method, PEReader reader, DecompilerTypeSystem typeSystem, HashSet<string> namespaces, bool scanningFullType = false)
{ {
var instructions = method.GetILReader(); var instructions = method.GetILReader();
var metadata = reader.GetMetadataReader(); var metadata = reader.GetMetadataReader();
@ -174,7 +178,7 @@ namespace ICSharpCode.Decompiler.CSharp
if (handle.Kind.IsTypeKind()) if (handle.Kind.IsTypeKind())
CollectNamespacesForTypeReference(typeSystem.ResolveAsType(handle), namespaces); CollectNamespacesForTypeReference(typeSystem.ResolveAsType(handle), namespaces);
else else
CollectNamespacesForMemberReference(typeSystem.ResolveAsMember(handle), typeSystem, namespaces); CollectNamespacesForMemberReference(typeSystem.ResolveAsMember(handle), typeSystem, namespaces, scanningFullType: scanningFullType);
break; break;
default: default:
instructions.SkipOperand(opCode); instructions.SkipOperand(opCode);
@ -183,18 +187,18 @@ namespace ICSharpCode.Decompiler.CSharp
} }
} }
static void CollectNamespacesForMemberReference(IMember member, DecompilerTypeSystem typeSystem, HashSet<string> namespaces) static void CollectNamespacesForMemberReference(IMember member, DecompilerTypeSystem typeSystem, HashSet<string> namespaces, bool scanningFullType = false)
{ {
switch (member) { switch (member) {
case IField field: case IField field:
if (field.IsCompilerGeneratedOrIsInCompilerGeneratedClass()) if (!scanningFullType && field.IsCompilerGeneratedOrIsInCompilerGeneratedClass())
CollectNamespaces(field, typeSystem, namespaces); CollectNamespaces(field, typeSystem, namespaces);
else else
CollectNamespacesForTypeReference(field.DeclaringType, namespaces); CollectNamespacesForTypeReference(field.DeclaringType, namespaces);
CollectNamespacesForTypeReference(field.ReturnType, namespaces); CollectNamespacesForTypeReference(field.ReturnType, namespaces);
break; break;
case IMethod method: case IMethod method:
if (method.IsCompilerGeneratedOrIsInCompilerGeneratedClass()) if (!scanningFullType && method.IsCompilerGeneratedOrIsInCompilerGeneratedClass())
CollectNamespaces(method, typeSystem, namespaces); CollectNamespaces(method, typeSystem, namespaces);
else else
CollectNamespacesForTypeReference(method.DeclaringType, namespaces); CollectNamespacesForTypeReference(method.DeclaringType, namespaces);

Loading…
Cancel
Save