Browse Source

Fix #1233: Fix some crashes on corrupt type references.

pull/1243/head
Daniel Grunwald 7 years ago
parent
commit
8270a93c1a
  1. 8
      ICSharpCode.Decompiler/IL/InstructionOutputExtensions.cs
  2. 25
      ICSharpCode.Decompiler/SRMExtensions.cs
  3. 14
      ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeDefinition.cs
  4. 10
      ILSpy/TextView/DecompilerTextView.cs

8
ICSharpCode.Decompiler/IL/InstructionOutputExtensions.cs

@ -85,7 +85,13 @@ namespace ICSharpCode.Decompiler.IL
} }
case HandleKind.TypeReference: { case HandleKind.TypeReference: {
var tr = metadata.GetTypeReference((TypeReferenceHandle)entity); var tr = metadata.GetTypeReference((TypeReferenceHandle)entity);
if (!tr.ResolutionScope.IsNil) { EntityHandle resolutionScope;
try {
resolutionScope = tr.ResolutionScope;
} catch (BadImageFormatException) {
resolutionScope = default;
}
if (!resolutionScope.IsNil) {
output.Write("["); output.Write("[");
var currentTypeRef = tr; var currentTypeRef = tr;
while (currentTypeRef.ResolutionScope.Kind == HandleKind.TypeReference) { while (currentTypeRef.ResolutionScope.Kind == HandleKind.TypeReference) {

25
ICSharpCode.Decompiler/SRMExtensions.cs

@ -9,6 +9,7 @@ using System.Reflection.PortableExecutable;
using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.TypeSystem.Implementation; using ICSharpCode.Decompiler.TypeSystem.Implementation;
using ICSharpCode.Decompiler.Util; using ICSharpCode.Decompiler.Util;
using System.Reflection.Metadata.Ecma335;
namespace ICSharpCode.Decompiler namespace ICSharpCode.Decompiler
{ {
@ -193,11 +194,27 @@ namespace ICSharpCode.Decompiler
if (handle.IsNil) if (handle.IsNil)
throw new ArgumentNullException(nameof(handle)); throw new ArgumentNullException(nameof(handle));
var tr = reader.GetTypeReference(handle); var tr = reader.GetTypeReference(handle);
string name = ReflectionHelper.SplitTypeParameterCountFromReflectionName(reader.GetString(tr.Name), out var typeParameterCount); string name;
try {
name = reader.GetString(tr.Name);
} catch (BadImageFormatException) {
name = $"TR{reader.GetToken(handle):x8}";
}
name = ReflectionHelper.SplitTypeParameterCountFromReflectionName(name, out var typeParameterCount);
TypeReferenceHandle declaringTypeHandle; TypeReferenceHandle declaringTypeHandle;
if ((declaringTypeHandle = tr.GetDeclaringType()).IsNil) { try {
string @namespace = tr.Namespace.IsNil ? "" : reader.GetString(tr.Namespace); declaringTypeHandle = tr.GetDeclaringType();
return new FullTypeName(new TopLevelTypeName(@namespace, name, typeParameterCount)); } catch (BadImageFormatException) {
declaringTypeHandle = default;
}
if (declaringTypeHandle.IsNil) {
string ns;
try {
ns = tr.Namespace.IsNil ? "" : reader.GetString(tr.Namespace);
} catch (BadImageFormatException) {
ns = "";
}
return new FullTypeName(new TopLevelTypeName(ns, name, typeParameterCount));
} else { } else {
return declaringTypeHandle.GetFullTypeName(reader).NestedType(name, typeParameterCount); return declaringTypeHandle.GetFullTypeName(reader).NestedType(name, typeParameterCount);
} }

14
ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeDefinition.cs

@ -270,9 +270,17 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
var context = new GenericContext(TypeParameters); var context = new GenericContext(TypeParameters);
var interfaceImplCollection = td.GetInterfaceImplementations(); var interfaceImplCollection = td.GetInterfaceImplementations();
baseTypes = new List<IType>(1 + interfaceImplCollection.Count); baseTypes = new List<IType>(1 + interfaceImplCollection.Count);
EntityHandle baseType = td.GetBaseTypeOrNil(); IType baseType = null;
if (!baseType.IsNil) { try {
baseTypes.Add(module.ResolveType(baseType, context)); EntityHandle baseTypeHandle = td.BaseType;
if (!baseTypeHandle.IsNil) {
baseType = module.ResolveType(baseTypeHandle, context);
}
} catch (BadImageFormatException) {
baseType = SpecialType.UnknownType;
}
if (baseType != null) {
baseTypes.Add(baseType);
} else if (Kind == TypeKind.Interface) { } else if (Kind == TypeKind.Interface) {
// td.BaseType.IsNil is always true for interfaces, // td.BaseType.IsNil is always true for interfaces,
// but the type system expects every interface to derive from System.Object as well. // but the type system expects every interface to derive from System.Object as well.

10
ILSpy/TextView/DecompilerTextView.cs

@ -211,10 +211,14 @@ namespace ICSharpCode.ILSpy.TextView
return CreateTextBlockForEntity(entity); return CreateTextBlockForEntity(entity);
} else if (segment.Reference is ValueTuple<PEFile, System.Reflection.Metadata.EntityHandle> unresolvedEntity) { } else if (segment.Reference is ValueTuple<PEFile, System.Reflection.Metadata.EntityHandle> unresolvedEntity) {
var typeSystem = new DecompilerTypeSystem(unresolvedEntity.Item1, unresolvedEntity.Item1.GetAssemblyResolver(), TypeSystemOptions.Default | TypeSystemOptions.Uncached); var typeSystem = new DecompilerTypeSystem(unresolvedEntity.Item1, unresolvedEntity.Item1.GetAssemblyResolver(), TypeSystemOptions.Default | TypeSystemOptions.Uncached);
IEntity resolved = typeSystem.MainModule.ResolveEntity(unresolvedEntity.Item2); try {
if (resolved == null) IEntity resolved = typeSystem.MainModule.ResolveEntity(unresolvedEntity.Item2);
if (resolved == null)
return null;
return CreateTextBlockForEntity(resolved);
} catch (BadImageFormatException) {
return null; return null;
return CreateTextBlockForEntity(resolved); }
} }
return null; return null;
} }

Loading…
Cancel
Save