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 @@ -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<Action<ILNameSyntax>>? 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("<bad signature>");
}
output.Write(' ');
var parameters = methodDefinition.GetParameters();
@ -261,10 +267,10 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -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(") ");

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

@ -178,13 +178,18 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -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);
}

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

@ -152,8 +152,15 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -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<IParameter>.Array;
}
LazyInit.GetOrSet(ref this.returnType, returnType);
LazyInit.GetOrSet(ref this.parameters, parameters);
}
@ -204,10 +211,6 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -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);

28
ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataProperty.cs

@ -16,6 +16,7 @@ @@ -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 @@ -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<IParameter>.Array;
}
LazyInit.GetOrSet(ref this.returnType, returnType);
LazyInit.GetOrSet(ref this.parameters, parameters);
}

Loading…
Cancel
Save