Browse Source

Fix NullReferenceException in TypeSystemAstBuilder when attribute argument decoding fails.

pull/1030/head
Daniel Grunwald 7 years ago
parent
commit
fdc109eebd
  1. 2
      ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpOutputVisitor.cs
  2. 9
      ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs
  3. 1
      ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
  4. 5
      ICSharpCode.Decompiler/TypeSystem/IAttribute.cs
  5. 9
      ICSharpCode.Decompiler/TypeSystem/Implementation/CustomAttribute.cs
  6. 4
      ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultAttribute.cs

2
ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpOutputVisitor.cs

@ -1288,7 +1288,7 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor @@ -1288,7 +1288,7 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor
{
StartNode(attribute);
attribute.Type.AcceptVisitor(this);
if (attribute.Arguments.Count != 0 || !attribute.GetChildByRole(Roles.LPar).IsNull) {
if (attribute.Arguments.Count != 0 || attribute.HasArgumentList) {
Space(policy.SpaceBeforeMethodCallParentheses);
WriteCommaSeparatedListInParenthesis(attribute.Arguments, policy.SpaceWithinMethodCallParentheses);
}

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

@ -471,9 +471,16 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -471,9 +471,16 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
mt.MemberName = mt.MemberName.Substring(0, mt.MemberName.Length - 9);
}
var parameters = attribute.Constructor?.Parameters ?? EmptyList<IParameter>.Instance;
foreach (var (arg, p) in attribute.FixedArguments.ZipLongest(parameters)) {
for (int i = 0; i < attribute.FixedArguments.Length; i++) {
var arg = attribute.FixedArguments[i];
var p = (i < parameters.Count) ? parameters[i] : null;
attr.Arguments.Add(ConvertConstantValue(p?.Type ?? arg.Type, arg.Type, arg.Value));
}
if (attribute.HasDecodeErrors) {
attr.HasArgumentList = true;
attr.AddChild(new Comment("Could not decode attribute arguments.", CommentType.MultiLine), Roles.Comment);
attr.AddChild(new CSharpTokenNode(TextLocation.Empty, Roles.RPar), Roles.RPar);
}
if (attribute.NamedArguments.Length > 0) {
InitializedObjectResolveResult targetResult = new InitializedObjectResolveResult(attribute.AttributeType);
foreach (var namedArg in attribute.NamedArguments) {

1
ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj

@ -274,7 +274,6 @@ @@ -274,7 +274,6 @@
<Compile Include="Documentation\GetPotentiallyNestedClassTypeReference.cs" />
<Compile Include="Documentation\IdStringMemberReference.cs" />
<Compile Include="Documentation\IdStringProvider.cs" />
<Compile Include="Documentation\XmlDocKeyProvider.cs" />
<Compile Include="Documentation\XmlDocLoader.cs" />
<Compile Include="Documentation\XmlDocumentationProvider.cs" />
<Compile Include="IL\ControlFlow\AsyncAwaitDecompiler.cs" />

5
ICSharpCode.Decompiler/TypeSystem/IAttribute.cs

@ -40,6 +40,11 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -40,6 +40,11 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// </summary>
IMethod Constructor { get; }
/// <summary>
/// Gets whether there were errors decoding the attribute.
/// </summary>
bool HasDecodeErrors { get; }
/// <summary>
/// Gets the positional arguments.
/// </summary>

9
ICSharpCode.Decompiler/TypeSystem/Implementation/CustomAttribute.cs

@ -38,6 +38,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -38,6 +38,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
// lazy-loaded:
CustomAttributeValue<IType> value;
bool valueDecoded;
bool hasDecodeErrors;
internal CustomAttribute(MetadataModule module, IMethod attrCtor, CustomAttributeHandle handle)
{
@ -65,6 +66,13 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -65,6 +66,13 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
}
}
public bool HasDecodeErrors {
get {
DecodeValue();
return hasDecodeErrors;
}
}
void DecodeValue()
{
lock (this) {
@ -80,6 +88,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -80,6 +88,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
ImmutableArray<CustomAttributeTypedArgument<IType>>.Empty,
ImmutableArray<CustomAttributeNamedArgument<IType>>.Empty
);
hasDecodeErrors = true;
valueDecoded = true; // in case of errors, never try again.
}
}

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

@ -66,7 +66,9 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -66,7 +66,9 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
public IType AttributeType {
get { return attributeType; }
}
bool IAttribute.HasDecodeErrors => false;
public IMethod Constructor {
get {
IMethod ctor = this.constructor;

Loading…
Cancel
Save