Browse Source

Fix #1283: handle invalid metadata when decoding constants

pull/1360/head
Daniel Grunwald 7 years ago
parent
commit
72d755037b
  1. 40
      ICSharpCode.Decompiler.Tests/TypeSystem/TypeSystemLoaderTests.cs
  2. 17
      ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
  3. 2
      ICSharpCode.Decompiler/CSharp/CallBuilder.cs
  4. 2
      ICSharpCode.Decompiler/CSharp/Resolver/CSharpInvocationResolveResult.cs
  5. 2
      ICSharpCode.Decompiler/CSharp/Resolver/MemberLookup.cs
  6. 15
      ICSharpCode.Decompiler/CSharp/Syntax/Expressions/ErrorExpression.cs
  7. 34
      ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs
  8. 8
      ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs
  9. 2
      ICSharpCode.Decompiler/Semantics/LocalResolveResult.cs
  10. 4
      ICSharpCode.Decompiler/Semantics/MemberResolveResult.cs
  11. 4
      ICSharpCode.Decompiler/TypeSystem/IVariable.cs
  12. 10
      ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultParameter.cs
  13. 5
      ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultVariable.cs
  14. 2
      ICSharpCode.Decompiler/TypeSystem/Implementation/FakeMember.cs
  15. 19
      ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataField.cs
  16. 13
      ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataParameter.cs
  17. 4
      ICSharpCode.Decompiler/TypeSystem/Implementation/SpecializedField.cs
  18. 2
      ICSharpCode.Decompiler/TypeSystem/Implementation/SpecializedParameter.cs

40
ICSharpCode.Decompiler.Tests/TypeSystem/TypeSystemLoaderTests.cs

@ -496,24 +496,24 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem @@ -496,24 +496,24 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem
Assert.IsTrue(f.IsConst);
Assert.AreEqual(Accessibility.Public, f.Accessibility);
Assert.AreSame(e, f.Type);
Assert.AreEqual(typeof(short), f.ConstantValue.GetType());
Assert.AreEqual(typeof(short), f.GetConstantValue().GetType());
}
Assert.AreEqual("First", fields[0].Name);
Assert.AreEqual(0, fields[0].ConstantValue);
Assert.AreEqual(0, fields[0].GetConstantValue());
Assert.AreEqual("Second", fields[1].Name);
Assert.AreSame(e, fields[1].Type);
Assert.AreEqual(1, fields[1].ConstantValue);
Assert.AreEqual(1, fields[1].GetConstantValue());
Assert.AreEqual("Flag1", fields[2].Name);
Assert.AreEqual(0x10, fields[2].ConstantValue);
Assert.AreEqual(0x10, fields[2].GetConstantValue());
Assert.AreEqual("Flag2", fields[3].Name);
Assert.AreEqual(0x20, fields[3].ConstantValue);
Assert.AreEqual(0x20, fields[3].GetConstantValue());
Assert.AreEqual("CombinedFlags", fields[4].Name);
Assert.AreEqual(0x30, fields[4].ConstantValue);
Assert.AreEqual(0x30, fields[4].GetConstantValue());
}
[Test]
@ -773,7 +773,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem @@ -773,7 +773,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem
Assert.IsFalse(p.IsParams);
Assert.IsTrue(p.HasConstantValueInSignature);
Assert.AreEqual(0, p.GetAttributes().Count());
Assert.AreEqual(4, p.ConstantValue);
Assert.AreEqual(4, p.GetConstantValue());
}
[Test]
@ -799,7 +799,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem @@ -799,7 +799,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem
Assert.IsFalse(p.IsParams);
Assert.IsTrue(p.HasConstantValueInSignature);
Assert.AreEqual(0, p.GetAttributes().Count());
Assert.AreEqual((int)StringComparison.OrdinalIgnoreCase, p.ConstantValue);
Assert.AreEqual((int)StringComparison.OrdinalIgnoreCase, p.GetConstantValue());
}
[Test]
@ -812,7 +812,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem @@ -812,7 +812,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem
Assert.IsFalse(p.IsParams);
Assert.IsTrue(p.HasConstantValueInSignature);
Assert.AreEqual(0, p.GetAttributes().Count());
Assert.IsNull(p.ConstantValue);
Assert.IsNull(p.GetConstantValue());
}
[Test]
@ -824,8 +824,8 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem @@ -824,8 +824,8 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem
Assert.IsFalse(p.IsOut);
Assert.IsFalse(p.IsParams);
Assert.IsTrue(p.HasConstantValueInSignature);
Assert.AreEqual(1L, p.ConstantValue);
Assert.AreEqual(typeof(long), p.ConstantValue.GetType());
Assert.AreEqual(1L, p.GetConstantValue());
Assert.AreEqual(typeof(long), p.GetConstantValue().GetType());
}
[Test]
@ -837,8 +837,8 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem @@ -837,8 +837,8 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem
Assert.IsFalse(p.IsOut);
Assert.IsFalse(p.IsParams);
Assert.IsTrue(p.HasConstantValueInSignature);
Assert.AreEqual(1L, p.ConstantValue);
Assert.AreEqual(typeof(long), p.ConstantValue.GetType());
Assert.AreEqual(1L, p.GetConstantValue());
Assert.AreEqual(typeof(long), p.GetConstantValue().GetType());
}
[Test]
@ -850,8 +850,8 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem @@ -850,8 +850,8 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem
Assert.IsFalse(p.IsOut);
Assert.IsFalse(p.IsParams);
Assert.IsTrue(p.HasConstantValueInSignature);
Assert.AreEqual(1M, p.ConstantValue);
Assert.AreEqual(typeof(decimal), p.ConstantValue.GetType());
Assert.AreEqual(1M, p.GetConstantValue());
Assert.AreEqual(typeof(decimal), p.GetConstantValue().GetType());
}
[Test]
@ -1509,7 +1509,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem @@ -1509,7 +1509,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem
{
ITypeDefinition type = GetTypeDefinition(typeof(ClassWithMethodThatHasNullableDefaultParameter));
var method = type.GetMethods().Single(m => m.Name == "Foo");
Assert.AreEqual(42, method.Parameters.Single().ConstantValue);
Assert.AreEqual(42, method.Parameters.Single().GetConstantValue());
}
[Test]
@ -1529,7 +1529,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem @@ -1529,7 +1529,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem
{
var f = type.GetFields().Single(x => x.Name == name);
Assert.IsTrue(f.IsConst);
Assert.AreEqual(expected, f.ConstantValue);
Assert.AreEqual(expected, f.GetConstantValue());
Assert.AreEqual(0, f.GetAttributes().Count());
}
@ -1577,7 +1577,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem @@ -1577,7 +1577,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem
ITypeDefinition type = GetTypeDefinition(typeof(ConstantFieldTest));
IField field = type.Fields.Single(f => f.Name == "EnumFromThisAssembly");
Assert.IsTrue(field.IsConst);
Assert.AreEqual((short)MyEnum.Second, field.ConstantValue);
Assert.AreEqual((short)MyEnum.Second, field.GetConstantValue());
}
[Test]
@ -1586,7 +1586,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem @@ -1586,7 +1586,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem
ITypeDefinition type = GetTypeDefinition(typeof(ConstantFieldTest));
IField field = type.Fields.Single(f => f.Name == "EnumFromAnotherAssembly");
Assert.IsTrue(field.IsConst);
Assert.AreEqual((int)StringComparison.OrdinalIgnoreCase, field.ConstantValue);
Assert.AreEqual((int)StringComparison.OrdinalIgnoreCase, field.GetConstantValue());
}
[Test]
@ -1595,7 +1595,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem @@ -1595,7 +1595,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem
ITypeDefinition type = GetTypeDefinition(typeof(ConstantFieldTest));
IField field = type.Fields.Single(f => f.Name == "DefaultOfEnum");
Assert.IsTrue(field.IsConst);
Assert.AreEqual((short)default(MyEnum), field.ConstantValue);
Assert.AreEqual((short)default(MyEnum), field.GetConstantValue());
}
[Test]

17
ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

@ -998,7 +998,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -998,7 +998,7 @@ namespace ICSharpCode.Decompiler.CSharp
case EnumValueDisplayMode.None:
foreach (var enumMember in typeDecl.Members.OfType<EnumMemberDeclaration>()) {
enumMember.Initializer = null;
if (enumMember.GetSymbol() is IField f && f.ConstantValue == null) {
if (enumMember.GetSymbol() is IField f && f.GetConstantValue() == null) {
typeDecl.InsertChildBefore(enumMember, new Comment(" error: enumerator has no value"), Roles.Comment);
}
}
@ -1030,8 +1030,12 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1030,8 +1030,12 @@ namespace ICSharpCode.Decompiler.CSharp
bool first = true;
long firstValue = 0, previousValue = 0;
foreach (var field in typeDef.Fields) {
if (MemberIsHidden(module, field.MetadataToken, settings) || field.ConstantValue == null) continue;
long currentValue = (long)CSharpPrimitiveCast.Cast(TypeCode.Int64, field.ConstantValue, false);
if (MemberIsHidden(module, field.MetadataToken, settings))
continue;
object constantValue = field.GetConstantValue();
if (constantValue == null)
continue;
long currentValue = (long)CSharpPrimitiveCast.Cast(TypeCode.Int64, constantValue, false);
if (first) {
firstValue = currentValue;
first = false;
@ -1260,9 +1264,10 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1260,9 +1264,10 @@ namespace ICSharpCode.Decompiler.CSharp
var typeSystemAstBuilder = CreateAstBuilder(decompilationContext);
if (decompilationContext.CurrentTypeDefinition.Kind == TypeKind.Enum) {
var enumDec = new EnumMemberDeclaration { Name = field.Name };
if (field.ConstantValue != null) {
long initValue = (long)CSharpPrimitiveCast.Cast(TypeCode.Int64, field.ConstantValue, false);
enumDec.Initializer = typeSystemAstBuilder.ConvertConstantValue(decompilationContext.CurrentTypeDefinition.EnumUnderlyingType, field.ConstantValue);
object constantValue = field.GetConstantValue();
if (constantValue != null) {
long initValue = (long)CSharpPrimitiveCast.Cast(TypeCode.Int64, constantValue, false);
enumDec.Initializer = typeSystemAstBuilder.ConvertConstantValue(decompilationContext.CurrentTypeDefinition.EnumUnderlyingType, constantValue);
if (enumDec.Initializer is PrimitiveExpression primitive
&& initValue >= 0 && (decompilationContext.CurrentTypeDefinition.HasAttribute(KnownAttribute.Flags)
|| (initValue > 9 && (unchecked(initValue & (initValue - 1)) == 0 || unchecked(initValue & (initValue + 1)) == 0)))) {

2
ICSharpCode.Decompiler/CSharp/CallBuilder.cs

@ -714,7 +714,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -714,7 +714,7 @@ namespace ICSharpCode.Decompiler.CSharp
|| a.AttributeType.IsKnownType(KnownAttribute.CallerFilePath)
|| a.AttributeType.IsKnownType(KnownAttribute.CallerLineNumber)))
return false;
return object.Equals(parameter.ConstantValue, arg.ResolveResult.ConstantValue);
return object.Equals(parameter.GetConstantValue(), arg.ResolveResult.ConstantValue);
}
[Flags]

2
ICSharpCode.Decompiler/CSharp/Resolver/CSharpInvocationResolveResult.cs

@ -132,7 +132,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver @@ -132,7 +132,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
for (int i = 0; i < results.Length; i++) {
if (results[i] == null) {
if (Member.Parameters[i].IsOptional) {
results[i] = new ConstantResolveResult(Member.Parameters[i].Type, Member.Parameters[i].ConstantValue);
results[i] = new ConstantResolveResult(Member.Parameters[i].Type, Member.Parameters[i].GetConstantValue());
} else {
results[i] = ErrorResolveResult.UnknownError;
}

2
ICSharpCode.Decompiler/CSharp/Resolver/MemberLookup.cs

@ -684,7 +684,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver @@ -684,7 +684,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
return new MemberResolveResult(
targetResolveResult, field,
field.DeclaringTypeDefinition.EnumUnderlyingType,
field.IsConst, field.ConstantValue);
field.IsConst, field.GetConstantValue());
}
}
return new MemberResolveResult(targetResolveResult, resultGroup.NonMethod);

15
ICSharpCode.Decompiler/CSharp/Syntax/Expressions/ErrorExpression.cs

@ -52,22 +52,11 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -52,22 +52,11 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
{
}
public ErrorExpression (TextLocation location)
{
this.Location = location;
}
public ErrorExpression (string error)
{
this.Error = error;
}
public ErrorExpression (string error, TextLocation location)
{
this.Location = location;
this.Error = error;
AddChild(new Comment(error, CommentType.MultiLine), Roles.Comment);
}
public override void AcceptVisitor (IAstVisitor visitor)
{
visitor.VisitErrorNode(this);

34
ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs

@ -852,8 +852,11 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -852,8 +852,11 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
{
ITypeDefinition enumDefinition = type.GetDefinition();
TypeCode enumBaseTypeCode = ReflectionHelper.GetTypeCode(enumDefinition.EnumUnderlyingType);
foreach (IField field in enumDefinition.Fields) {
if (field.IsConst && object.Equals(CSharpPrimitiveCast.Cast(TypeCode.Int64, field.ConstantValue, false), val)) {
foreach (IField field in enumDefinition.Fields.Where(fld => fld.IsConst)) {
object constantValue = field.GetConstantValue();
if (constantValue == null)
continue;
if (object.Equals(CSharpPrimitiveCast.Cast(TypeCode.Int64, constantValue, false), val)) {
MemberReferenceExpression mre = new MemberReferenceExpression(new TypeReferenceExpression(ConvertType(type)), field.Name);
if (AddResolveResultAnnotations)
mre.AddAnnotation(new MemberResolveResult(mre.Target.GetResolveResult(), field));
@ -881,7 +884,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -881,7 +884,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
}
Expression negatedExpr = null;
foreach (IField field in enumDefinition.Fields.Where(fld => fld.IsConst)) {
long fieldValue = (long)CSharpPrimitiveCast.Cast(TypeCode.Int64, field.ConstantValue, false);
object constantValue = field.GetConstantValue();
long fieldValue = (long)CSharpPrimitiveCast.Cast(TypeCode.Int64, constantValue, false);
if (fieldValue == 0)
continue; // skip None enum value
@ -946,7 +950,11 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -946,7 +950,11 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
decl.Name = parameter.Name;
}
if (parameter.IsOptional && parameter.HasConstantValueInSignature && this.ShowConstantValues) {
decl.DefaultExpression = ConvertConstantValue(parameter.Type, parameter.ConstantValue);
try {
decl.DefaultExpression = ConvertConstantValue(parameter.Type, parameter.GetConstantValue(throwOnInvalidMetadata: true));
} catch (BadImageFormatException ex) {
decl.DefaultExpression = new ErrorExpression(ex.Message);
}
}
return decl;
}
@ -1158,8 +1166,13 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -1158,8 +1166,13 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
}
decl.ReturnType = ConvertType(field.ReturnType);
Expression initializer = null;
if (field.IsConst && this.ShowConstantValues)
initializer = ConvertConstantValue(field.Type, field.ConstantValue);
if (field.IsConst && this.ShowConstantValues) {
try {
initializer = ConvertConstantValue(field.Type, field.GetConstantValue(throwOnInvalidMetadata: true));
} catch (BadImageFormatException ex) {
initializer = new ErrorExpression(ex.Message);
}
}
decl.Variables.Add(new VariableInitializer(field.Name, initializer));
return decl;
}
@ -1463,8 +1476,13 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -1463,8 +1476,13 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
decl.Modifiers = v.IsConst ? Modifiers.Const : Modifiers.None;
decl.Type = ConvertType(v.Type);
Expression initializer = null;
if (v.IsConst)
initializer = ConvertConstantValue(v.Type, v.ConstantValue);
if (v.IsConst) {
try {
initializer = ConvertConstantValue(v.Type, v.GetConstantValue(throwOnInvalidMetadata: true));
} catch (BadImageFormatException ex) {
initializer = new ErrorExpression(ex.Message);
}
}
decl.Variables.Add(new VariableInitializer(v.Name, initializer));
return decl;
}

8
ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs

@ -1025,7 +1025,13 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -1025,7 +1025,13 @@ namespace ICSharpCode.Decompiler.Disassembler
break;
default:
var blob = metadata.GetBlobReader(constant.Value);
var value = blob.ReadConstant(constant.TypeCode);
object value;
try {
value = blob.ReadConstant(constant.TypeCode);
} catch (ArgumentOutOfRangeException) {
output.Write($"/* Constant with invalid typecode: {constant.TypeCode} */");
return;
}
if (value is string) {
DisassemblerHelpers.WriteOperand(output, value);
} else {

2
ICSharpCode.Decompiler/Semantics/LocalResolveResult.cs

@ -61,7 +61,7 @@ namespace ICSharpCode.Decompiler.Semantics @@ -61,7 +61,7 @@ namespace ICSharpCode.Decompiler.Semantics
}
public override object ConstantValue {
get { return IsParameter ? null : variable.ConstantValue; }
get { return IsParameter ? null : variable.GetConstantValue(); }
}
public override string ToString()

4
ICSharpCode.Decompiler/Semantics/MemberResolveResult.cs

@ -48,7 +48,7 @@ namespace ICSharpCode.Decompiler.Semantics @@ -48,7 +48,7 @@ namespace ICSharpCode.Decompiler.Semantics
if (field != null) {
isConstant = field.IsConst;
if (isConstant)
constantValue = field.ConstantValue;
constantValue = field.GetConstantValue();
}
}
@ -62,7 +62,7 @@ namespace ICSharpCode.Decompiler.Semantics @@ -62,7 +62,7 @@ namespace ICSharpCode.Decompiler.Semantics
if (field != null) {
isConstant = field.IsConst;
if (isConstant)
constantValue = field.ConstantValue;
constantValue = field.GetConstantValue();
}
}

4
ICSharpCode.Decompiler/TypeSystem/IVariable.cs

@ -37,11 +37,11 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -37,11 +37,11 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// Gets whether this variable is a constant (C#-like const).
/// </summary>
bool IsConst { get; }
/// <summary>
/// If this field is a constant, retrieves the value.
/// For parameters, this is the default value.
/// </summary>
object ConstantValue { get; }
object GetConstantValue(bool throwOnInvalidMetadata = false);
}
}

10
ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultParameter.cs

@ -111,8 +111,9 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -111,8 +111,9 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
get { return IsOptional; }
}
public object ConstantValue {
get { return defaultValue; }
public object GetConstantValue(bool throwOnInvalidMetadata)
{
return defaultValue;
}
public override string ToString()
@ -134,8 +135,9 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -134,8 +135,9 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
b.Append(parameter.Type.ReflectionName);
if (parameter.IsOptional && parameter.HasConstantValueInSignature) {
b.Append(" = ");
if (parameter.ConstantValue != null)
b.Append(parameter.ConstantValue.ToString());
object val = parameter.GetConstantValue(throwOnInvalidMetadata: false);
if (val != null)
b.Append(val.ToString());
else
b.Append("null");
}

5
ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultVariable.cs

@ -60,8 +60,9 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -60,8 +60,9 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
get { return isConst; }
}
public object ConstantValue {
get { return constantValue; }
public object GetConstantValue(bool throwOnInvalidMetadata)
{
return constantValue;
}
public SymbolKind SymbolKind {

2
ICSharpCode.Decompiler/TypeSystem/Implementation/FakeMember.cs

@ -108,7 +108,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -108,7 +108,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
bool IField.IsVolatile => false;
bool IVariable.IsConst => false;
object IVariable.ConstantValue => null;
object IVariable.GetConstantValue(bool throwOnInvalidMetadata) => null;
IType IVariable.Type => ReturnType;
public override SymbolKind SymbolKind => SymbolKind.Field;

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

@ -201,11 +201,12 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -201,11 +201,12 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
}
}
public object ConstantValue {
get {
object val = LazyInit.VolatileRead(ref this.constantValue);
if (val != null)
return val;
public object GetConstantValue(bool throwOnInvalidMetadata)
{
object val = LazyInit.VolatileRead(ref this.constantValue);
if (val != null)
return val;
try {
var metadata = module.metadata;
var fieldDef = metadata.GetFieldDefinition(handle);
if (IsDecimalConstant && DecimalConstantHelper.AllowsDecimalConstants(module)) {
@ -216,9 +217,15 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -216,9 +217,15 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
return null;
var constant = metadata.GetConstant(constantHandle);
var blobReader = metadata.GetBlobReader(constant.Value);
val = blobReader.ReadConstant(constant.TypeCode);
try {
val = blobReader.ReadConstant(constant.TypeCode);
} catch (ArgumentOutOfRangeException) {
throw new BadImageFormatException($"Constant with invalid typecode: {constant.TypeCode}");
}
}
return LazyInit.GetOrSet(ref this.constantValue, val);
} catch (BadImageFormatException) when (!throwOnInvalidMetadata) {
return null;
}
}

13
ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataParameter.cs

@ -130,8 +130,9 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -130,8 +130,9 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
bool IVariable.IsConst => false;
public object ConstantValue {
get {
public object GetConstantValue(bool throwOnInvalidMetadata)
{
try {
var metadata = module.metadata;
var parameterDef = metadata.GetParameter(handle);
if (IsDecimalConstant)
@ -143,7 +144,13 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -143,7 +144,13 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
var constant = metadata.GetConstant(constantHandle);
var blobReader = metadata.GetBlobReader(constant.Value);
return blobReader.ReadConstant(constant.TypeCode);
try {
return blobReader.ReadConstant(constant.TypeCode);
} catch (ArgumentOutOfRangeException) {
throw new BadImageFormatException($"Constant with invalid typecode: {constant.TypeCode}");
}
} catch (BadImageFormatException) when (!throwOnInvalidMetadata) {
return null;
}
}

4
ICSharpCode.Decompiler/TypeSystem/Implementation/SpecializedField.cs

@ -60,8 +60,8 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -60,8 +60,8 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
get { return fieldDefinition.IsConst; }
}
public object ConstantValue {
get { return fieldDefinition.ConstantValue; }
public object GetConstantValue(bool throwOnInvalidMetadata) {
return fieldDefinition.GetConstantValue(throwOnInvalidMetadata);
}
}
}

2
ICSharpCode.Decompiler/TypeSystem/Implementation/SpecializedParameter.cs

@ -47,7 +47,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -47,7 +47,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
string ISymbol.Name => baseParameter.Name;
IType IVariable.Type => newType;
bool IVariable.IsConst => baseParameter.IsConst;
object IVariable.ConstantValue => baseParameter.ConstantValue;
object IVariable.GetConstantValue(bool throwOnInvalidMetadata) => baseParameter.GetConstantValue(throwOnInvalidMetadata);
SymbolKind ISymbol.SymbolKind => SymbolKind.Parameter;
public override string ToString()

Loading…
Cancel
Save