Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/cecil.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVitek Karas <10670590+vitek-karas@users.noreply.github.com>2022-02-22 02:07:22 +0300
committerGitHub <noreply@github.com>2022-02-22 02:07:22 +0300
commitf7b64f756021c546d303e55413f10967728ad8ba (patch)
treeded906fa8e5b55390451fa648c2bcfa599ff9f28 /Mono.Cecil
parent79b43e8e72866f450dee8b59510cb5767b1491ec (diff)
Fix custom attribute with enum on generic type (#827)
* Fix custom attribute with enum on generic type Fixes both the reader and the write to correctly handle values of type enum on a generic type. Cecil represents generic instantiations as typeref which has etype GenericInst, so the exising check for etype doesn't work. Also since attributes only allow simple values and enums (and types), there's technically no other way to get a GenericInst then the enum case. Added several test for various combinations of boxed an unboxed enums on generic type. Added a test case provided by @mrvoorhe with array of such enums. * Disable the new tests on .NET 4 The CodeDom compiler doesn't support parsing enums on generic types in attributes (uses the "old" csc.exe from framework).
Diffstat (limited to 'Mono.Cecil')
-rw-r--r--Mono.Cecil/AssemblyReader.cs6
-rw-r--r--Mono.Cecil/AssemblyWriter.cs12
2 files changed, 18 insertions, 0 deletions
diff --git a/Mono.Cecil/AssemblyReader.cs b/Mono.Cecil/AssemblyReader.cs
index b66c162..ee2c229 100644
--- a/Mono.Cecil/AssemblyReader.cs
+++ b/Mono.Cecil/AssemblyReader.cs
@@ -3598,6 +3598,12 @@ namespace Mono.Cecil {
object ReadCustomAttributeElementValue (TypeReference type)
{
var etype = type.etype;
+ if (etype == ElementType.GenericInst) {
+ // The only way to get a generic here is that it's an enum on a generic type
+ // so for enum we don't need to know the generic arguments (they have no effect)
+ type = type.GetElementType ();
+ etype = type.etype;
+ }
switch (etype) {
case ElementType.String:
diff --git a/Mono.Cecil/AssemblyWriter.cs b/Mono.Cecil/AssemblyWriter.cs
index 25076ff..3cba95e 100644
--- a/Mono.Cecil/AssemblyWriter.cs
+++ b/Mono.Cecil/AssemblyWriter.cs
@@ -2993,6 +2993,10 @@ namespace Mono.Cecil {
else
WriteCustomAttributeEnumValue (type, value);
break;
+ case ElementType.GenericInst:
+ // Generic instantiation can only happen for an enum (no other generic like types can appear in attribute value)
+ WriteCustomAttributeEnumValue (type, value);
+ break;
default:
WritePrimitiveValue (value);
break;
@@ -3099,6 +3103,14 @@ namespace Mono.Cecil {
WriteTypeReference (type);
}
return;
+ case ElementType.GenericInst:
+ // Generic instantiation can really only happen if it's an enum type since no other
+ // types are allowed in the attribute value.
+ // Enums are special in attribute data, they're encoded as ElementType.Enum followed by a typeref
+ // followed by the value.
+ WriteElementType (ElementType.Enum);
+ WriteTypeReference (type);
+ return;
default:
WriteElementType (etype);
return;