Browse Source

Fix #1529: Handle exceptions on invalid metadata signatures

pull/1556/head
Daniel Grunwald 6 years ago
parent
commit
7f2b3a4506
  1. 32
      ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs
  2. 17
      ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataField.cs
  3. 15
      ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataMethod.cs
  4. 28
      ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataProperty.cs

32
ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs

@ -225,19 +225,25 @@ namespace ICSharpCode.Decompiler.Disassembler
output.WriteLine(); output.WriteLine();
output.Indent(); output.Indent();
var declaringType = methodDefinition.GetDeclaringType(); var declaringType = methodDefinition.GetDeclaringType();
var signatureProvider = new DisassemblerSignatureProvider(module, output); MethodSignature<Action<ILNameSyntax>>? signature;
var signature = methodDefinition.DecodeSignature(signatureProvider, genericContext); try {
if (signature.Header.HasExplicitThis) { var signatureProvider = new DisassemblerSignatureProvider(module, output);
output.Write("instance explicit "); signature = methodDefinition.DecodeSignature(signatureProvider, genericContext);
} else if (signature.Header.IsInstance) { if (signature.Value.Header.HasExplicitThis) {
output.Write("instance "); output.Write("instance explicit ");
} } else if (signature.Value.Header.IsInstance) {
output.Write("instance ");
}
//call convention //call convention
WriteEnum(signature.Header.CallingConvention, callingConvention); WriteEnum(signature.Value.Header.CallingConvention, callingConvention);
//return type //return type
signature.ReturnType(ILNameSyntax.Signature); signature.Value.ReturnType(ILNameSyntax.Signature);
} catch (BadImageFormatException) {
signature = null;
output.Write("<bad signature>");
}
output.Write(' '); output.Write(' ');
var parameters = methodDefinition.GetParameters(); var parameters = methodDefinition.GetParameters();
@ -261,10 +267,10 @@ namespace ICSharpCode.Decompiler.Disassembler
//( params ) //( params )
output.Write(" ("); output.Write(" (");
if (signature.ParameterTypes.Length > 0) { if (signature?.ParameterTypes.Length > 0) {
output.WriteLine(); output.WriteLine();
output.Indent(); output.Indent();
WriteParameters(metadata, parameters, signature); WriteParameters(metadata, parameters, signature.Value);
output.Unindent(); output.Unindent();
} }
output.Write(") "); output.Write(") ");

17
ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataField.cs

@ -178,13 +178,18 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
{ {
var metadata = module.metadata; var metadata = module.metadata;
var fieldDef = metadata.GetFieldDefinition(handle); var fieldDef = metadata.GetFieldDefinition(handle);
var ty = fieldDef.DecodeSignature(module.TypeProvider, new GenericContext(DeclaringType?.TypeParameters)); IType ty;
if (ty is ModifiedType mod && mod.Modifier.Name == "IsVolatile" && mod.Modifier.Namespace == "System.Runtime.CompilerServices") { try {
Volatile.Write(ref this.isVolatile, true); ty = fieldDef.DecodeSignature(module.TypeProvider, new GenericContext(DeclaringType?.TypeParameters));
ty = mod.ElementType; 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); return LazyInit.GetOrSet(ref this.type, ty);
} }

15
ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataMethod.cs

@ -152,8 +152,15 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
{ {
var methodDef = module.metadata.GetMethodDefinition(handle); var methodDef = module.metadata.GetMethodDefinition(handle);
var genericContext = new GenericContext(DeclaringType.TypeParameters, this.TypeParameters); var genericContext = new GenericContext(DeclaringType.TypeParameters, this.TypeParameters);
var signature = methodDef.DecodeSignature(module.TypeProvider, genericContext); IType returnType;
var (returnType, parameters) = DecodeSignature(module, this, signature, methodDef.GetParameters()); 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<IParameter>.Array;
}
LazyInit.GetOrSet(ref this.returnType, returnType); LazyInit.GetOrSet(ref this.returnType, returnType);
LazyInit.GetOrSet(ref this.parameters, parameters); LazyInit.GetOrSet(ref this.parameters, parameters);
} }
@ -204,10 +211,6 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
i++; i++;
} }
Debug.Assert(i == parameters.Length); 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, var returnType = ApplyAttributeTypeVisitor.ApplyAttributesToType(signature.ReturnType,
module.Compilation, returnTypeAttributes, metadata, module.TypeSystemOptions); module.Compilation, returnTypeAttributes, metadata, module.TypeSystemOptions);
return (returnType, parameters); return (returnType, parameters);

28
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 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
@ -116,16 +117,23 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
{ {
var propertyDef = module.metadata.GetPropertyDefinition(propertyHandle); var propertyDef = module.metadata.GetPropertyDefinition(propertyHandle);
var genericContext = new GenericContext(DeclaringType.TypeParameters); var genericContext = new GenericContext(DeclaringType.TypeParameters);
var signature = propertyDef.DecodeSignature(module.TypeProvider, genericContext); IType returnType;
var accessors = propertyDef.GetAccessors(); IParameter[] parameters;
ParameterHandleCollection? parameterHandles; try {
if (!accessors.Getter.IsNil) var signature = propertyDef.DecodeSignature(module.TypeProvider, genericContext);
parameterHandles = module.metadata.GetMethodDefinition(accessors.Getter).GetParameters(); var accessors = propertyDef.GetAccessors();
else if (!accessors.Setter.IsNil) ParameterHandleCollection? parameterHandles;
parameterHandles = module.metadata.GetMethodDefinition(accessors.Setter).GetParameters(); if (!accessors.Getter.IsNil)
else parameterHandles = module.metadata.GetMethodDefinition(accessors.Getter).GetParameters();
parameterHandles = null; else if (!accessors.Setter.IsNil)
var (returnType, parameters) = MetadataMethod.DecodeSignature(module, this, signature, parameterHandles); 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<IParameter>.Array;
}
LazyInit.GetOrSet(ref this.returnType, returnType); LazyInit.GetOrSet(ref this.returnType, returnType);
LazyInit.GetOrSet(ref this.parameters, parameters); LazyInit.GetOrSet(ref this.parameters, parameters);
} }

Loading…
Cancel
Save