From 7f2b3a45066684ca04f792e3189120b960845ae6 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Sat, 8 Jun 2019 21:59:24 +0200 Subject: [PATCH] Fix #1529: Handle exceptions on invalid metadata signatures --- .../Disassembler/ReflectionDisassembler.cs | 32 +++++++++++-------- .../Implementation/MetadataField.cs | 17 ++++++---- .../Implementation/MetadataMethod.cs | 15 +++++---- .../Implementation/MetadataProperty.cs | 28 ++++++++++------ 4 files changed, 57 insertions(+), 35 deletions(-) diff --git a/ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs b/ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs index 1bee541e2..a542eece4 100644 --- a/ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs +++ b/ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs @@ -225,19 +225,25 @@ namespace ICSharpCode.Decompiler.Disassembler output.WriteLine(); output.Indent(); var declaringType = methodDefinition.GetDeclaringType(); - var signatureProvider = new DisassemblerSignatureProvider(module, output); - var signature = methodDefinition.DecodeSignature(signatureProvider, genericContext); - if (signature.Header.HasExplicitThis) { - output.Write("instance explicit "); - } else if (signature.Header.IsInstance) { - output.Write("instance "); - } + MethodSignature>? signature; + try { + var signatureProvider = new DisassemblerSignatureProvider(module, output); + signature = methodDefinition.DecodeSignature(signatureProvider, genericContext); + if (signature.Value.Header.HasExplicitThis) { + output.Write("instance explicit "); + } else if (signature.Value.Header.IsInstance) { + output.Write("instance "); + } - //call convention - WriteEnum(signature.Header.CallingConvention, callingConvention); + //call convention + WriteEnum(signature.Value.Header.CallingConvention, callingConvention); - //return type - signature.ReturnType(ILNameSyntax.Signature); + //return type + signature.Value.ReturnType(ILNameSyntax.Signature); + } catch (BadImageFormatException) { + signature = null; + output.Write(""); + } output.Write(' '); var parameters = methodDefinition.GetParameters(); @@ -261,10 +267,10 @@ namespace ICSharpCode.Decompiler.Disassembler //( params ) output.Write(" ("); - if (signature.ParameterTypes.Length > 0) { + if (signature?.ParameterTypes.Length > 0) { output.WriteLine(); output.Indent(); - WriteParameters(metadata, parameters, signature); + WriteParameters(metadata, parameters, signature.Value); output.Unindent(); } output.Write(") "); diff --git a/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataField.cs b/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataField.cs index 9ff7a1849..00d034bb5 100644 --- a/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataField.cs +++ b/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataField.cs @@ -178,13 +178,18 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation { var metadata = module.metadata; var fieldDef = metadata.GetFieldDefinition(handle); - var ty = fieldDef.DecodeSignature(module.TypeProvider, new GenericContext(DeclaringType?.TypeParameters)); - if (ty is ModifiedType mod && mod.Modifier.Name == "IsVolatile" && mod.Modifier.Namespace == "System.Runtime.CompilerServices") { - Volatile.Write(ref this.isVolatile, true); - ty = mod.ElementType; + IType ty; + try { + ty = fieldDef.DecodeSignature(module.TypeProvider, new GenericContext(DeclaringType?.TypeParameters)); + if (ty is ModifiedType mod && mod.Modifier.Name == "IsVolatile" && mod.Modifier.Namespace == "System.Runtime.CompilerServices") { + Volatile.Write(ref this.isVolatile, true); + ty = mod.ElementType; + } + ty = ApplyAttributeTypeVisitor.ApplyAttributesToType(ty, Compilation, + fieldDef.GetCustomAttributes(), metadata, module.TypeSystemOptions); + } catch (BadImageFormatException) { + ty = SpecialType.UnknownType; } - ty = ApplyAttributeTypeVisitor.ApplyAttributesToType(ty, Compilation, - fieldDef.GetCustomAttributes(), metadata, module.TypeSystemOptions); return LazyInit.GetOrSet(ref this.type, ty); } diff --git a/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataMethod.cs b/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataMethod.cs index 9cb6a308e..2406051e3 100644 --- a/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataMethod.cs +++ b/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataMethod.cs @@ -152,8 +152,15 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation { var methodDef = module.metadata.GetMethodDefinition(handle); var genericContext = new GenericContext(DeclaringType.TypeParameters, this.TypeParameters); - var signature = methodDef.DecodeSignature(module.TypeProvider, genericContext); - var (returnType, parameters) = DecodeSignature(module, this, signature, methodDef.GetParameters()); + IType returnType; + IParameter[] parameters; + try { + var signature = methodDef.DecodeSignature(module.TypeProvider, genericContext); + (returnType, parameters) = DecodeSignature(module, this, signature, methodDef.GetParameters()); + } catch (BadImageFormatException) { + returnType = SpecialType.UnknownType; + parameters = Empty.Array; + } LazyInit.GetOrSet(ref this.returnType, returnType); LazyInit.GetOrSet(ref this.parameters, parameters); } @@ -204,10 +211,6 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation i++; } Debug.Assert(i == parameters.Length); - bool isRefReadonly = false; - if (signature.ReturnType.Kind == TypeKind.ModReq && signature.ReturnType.SkipModifiers().Kind == TypeKind.ByReference) { - isRefReadonly = ((ModifiedType)signature.ReturnType).Modifier.IsKnownType(KnownAttribute.In); - } var returnType = ApplyAttributeTypeVisitor.ApplyAttributesToType(signature.ReturnType, module.Compilation, returnTypeAttributes, metadata, module.TypeSystemOptions); return (returnType, parameters); diff --git a/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataProperty.cs b/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataProperty.cs index f0204a4b9..65eaeda55 100644 --- a/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataProperty.cs +++ b/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataProperty.cs @@ -16,6 +16,7 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; @@ -116,16 +117,23 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation { var propertyDef = module.metadata.GetPropertyDefinition(propertyHandle); var genericContext = new GenericContext(DeclaringType.TypeParameters); - var signature = propertyDef.DecodeSignature(module.TypeProvider, genericContext); - var accessors = propertyDef.GetAccessors(); - ParameterHandleCollection? parameterHandles; - if (!accessors.Getter.IsNil) - parameterHandles = module.metadata.GetMethodDefinition(accessors.Getter).GetParameters(); - else if (!accessors.Setter.IsNil) - parameterHandles = module.metadata.GetMethodDefinition(accessors.Setter).GetParameters(); - else - parameterHandles = null; - var (returnType, parameters) = MetadataMethod.DecodeSignature(module, this, signature, parameterHandles); + IType returnType; + IParameter[] parameters; + try { + var signature = propertyDef.DecodeSignature(module.TypeProvider, genericContext); + var accessors = propertyDef.GetAccessors(); + ParameterHandleCollection? parameterHandles; + if (!accessors.Getter.IsNil) + parameterHandles = module.metadata.GetMethodDefinition(accessors.Getter).GetParameters(); + else if (!accessors.Setter.IsNil) + parameterHandles = module.metadata.GetMethodDefinition(accessors.Setter).GetParameters(); + else + parameterHandles = null; + (returnType, parameters) = MetadataMethod.DecodeSignature(module, this, signature, parameterHandles); + } catch (BadImageFormatException) { + returnType = SpecialType.UnknownType; + parameters = Empty.Array; + } LazyInit.GetOrSet(ref this.returnType, returnType); LazyInit.GetOrSet(ref this.parameters, parameters); }