From b20d4df95b8d2e2b944c3a413e1a88335fa8a92c Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Mon, 23 Jul 2018 11:55:39 +0200 Subject: [PATCH] Fix #1231: System.BadImageFormatException: Invalid coded index --- .../Disassembler/ReflectionDisassembler.cs | 6 +++-- ICSharpCode.Decompiler/SRMExtensions.cs | 23 ++++++++++++++----- .../Implementation/MetadataTypeDefinition.cs | 5 ++-- ILSpy/TreeNodes/DerivedTypesTreeNode.cs | 3 ++- 4 files changed, 26 insertions(+), 11 deletions(-) diff --git a/ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs b/ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs index c40bec965..ca32f0eb6 100644 --- a/ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs +++ b/ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs @@ -1274,13 +1274,15 @@ namespace ICSharpCode.Decompiler.Disassembler output.MarkFoldStart(defaultCollapsed: !ExpandMemberDefinitions && isInType); output.WriteLine(); - if (!typeDefinition.BaseType.IsNil) { + EntityHandle baseType = typeDefinition.GetBaseTypeOrNil(); + if (!baseType.IsNil) { output.Indent(); output.Write("extends "); - typeDefinition.BaseType.WriteTo(module, output, genericContext, ILNameSyntax.TypeName); + baseType.WriteTo(module, output, genericContext, ILNameSyntax.TypeName); output.WriteLine(); output.Unindent(); } + var interfaces = typeDefinition.GetInterfaceImplementations(); if (interfaces.Count > 0) { output.Indent(); diff --git a/ICSharpCode.Decompiler/SRMExtensions.cs b/ICSharpCode.Decompiler/SRMExtensions.cs index b95384ac1..16701022b 100644 --- a/ICSharpCode.Decompiler/SRMExtensions.cs +++ b/ICSharpCode.Decompiler/SRMExtensions.cs @@ -31,7 +31,7 @@ namespace ICSharpCode.Decompiler public static bool IsValueType(this TypeDefinition typeDefinition, MetadataReader reader) { - var baseType = typeDefinition.BaseType; + EntityHandle baseType = typeDefinition.GetBaseTypeOrNil(); if (baseType.IsNil) return false; if (baseType.IsKnownType(reader, KnownTypeCode.Enum)) @@ -49,9 +49,10 @@ namespace ICSharpCode.Decompiler public static bool IsEnum(this TypeDefinition typeDefinition, MetadataReader reader) { - if (typeDefinition.BaseType.IsNil) + EntityHandle baseType = typeDefinition.GetBaseTypeOrNil(); + if (baseType.IsNil) return false; - return typeDefinition.BaseType.IsKnownType(reader, KnownTypeCode.Enum); + return baseType.IsKnownType(reader, KnownTypeCode.Enum); } public static bool IsEnum(this TypeDefinitionHandle handle, MetadataReader reader, out PrimitiveTypeCode underlyingType) @@ -62,9 +63,10 @@ namespace ICSharpCode.Decompiler public static bool IsEnum(this TypeDefinition typeDefinition, MetadataReader reader, out PrimitiveTypeCode underlyingType) { underlyingType = 0; - if (typeDefinition.BaseType.IsNil) + EntityHandle baseType = typeDefinition.GetBaseTypeOrNil(); + if (baseType.IsNil) return false; - if (!typeDefinition.BaseType.IsKnownType(reader, KnownTypeCode.Enum)) + if (!baseType.IsKnownType(reader, KnownTypeCode.Enum)) return false; var field = reader.GetFieldDefinition(typeDefinition.GetFields().First()); var blob = reader.GetBlobReader(field.Signature); @@ -81,7 +83,7 @@ namespace ICSharpCode.Decompiler public static bool IsDelegate(this TypeDefinition typeDefinition, MetadataReader reader) { - var baseType = typeDefinition.BaseType; + var baseType = typeDefinition.GetBaseTypeOrNil(); return !baseType.IsNil && baseType.IsKnownType(reader, KnownTypeCode.MulticastDelegate); } @@ -411,5 +413,14 @@ namespace ICSharpCode.Decompiler return reader.GetTypeSpecification(handle).DecodeSignature(this, genericContext); } } + + public static EntityHandle GetBaseTypeOrNil(this TypeDefinition definition) + { + try { + return definition.BaseType; + } catch (BadImageFormatException) { + return default; + } + } } } diff --git a/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeDefinition.cs b/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeDefinition.cs index 5ce947761..34cd8ab32 100644 --- a/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeDefinition.cs +++ b/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeDefinition.cs @@ -270,8 +270,9 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation var context = new GenericContext(TypeParameters); var interfaceImplCollection = td.GetInterfaceImplementations(); baseTypes = new List(1 + interfaceImplCollection.Count); - if (!td.BaseType.IsNil) { - baseTypes.Add(module.ResolveType(td.BaseType, context)); + EntityHandle baseType = td.GetBaseTypeOrNil(); + if (!baseType.IsNil) { + baseTypes.Add(module.ResolveType(baseType, context)); } else if (Kind == TypeKind.Interface) { // td.BaseType.IsNil is always true for interfaces, // but the type system expects every interface to derive from System.Object as well. diff --git a/ILSpy/TreeNodes/DerivedTypesTreeNode.cs b/ILSpy/TreeNodes/DerivedTypesTreeNode.cs index 456805362..bd82ebac5 100644 --- a/ILSpy/TreeNodes/DerivedTypesTreeNode.cs +++ b/ILSpy/TreeNodes/DerivedTypesTreeNode.cs @@ -76,7 +76,8 @@ namespace ICSharpCode.ILSpy.TreeNodes if (IsSameType(metadata, ifaceImpl.Interface, definitionMetadata, metadataToken)) yield return new DerivedTypesEntryNode(list, assembly.GetDefinition(h)); } - if (!td.BaseType.IsNil && IsSameType(metadata, td.BaseType, definitionMetadata, metadataToken)) { + SRM.EntityHandle baseType = td.GetBaseTypeOrNil(); + if (!baseType.IsNil && IsSameType(metadata, baseType, definitionMetadata, metadataToken)) { yield return new DerivedTypesEntryNode(list, assembly.GetDefinition(h)); } }