Skip to content

Commit 9bcf80b

Browse files
committed
Core: Fix exception when attempting to serialize null array as CA arg
1 parent 894ab4f commit 9bcf80b

10 files changed

+177
-91
lines changed

Cpp2IL.Core/CorePlugin/AttributeInjectorProcessingLayer.cs

+9-9
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ private static void InjectFieldOffsetAttribute(ApplicationAnalysisContext appCon
5454
var newAttribute = new AnalyzedCustomAttribute(fieldOffsetConstructor);
5555

5656
//This loop is not done parallel because f.Offset has heavy lock contention
57-
newAttribute.Fields.Add(new(offsetField, new CustomAttributePrimitiveParameter($"0x{f.Offset:X}")));
57+
newAttribute.Fields.Add(new(offsetField, new CustomAttributePrimitiveParameter($"0x{f.Offset:X}", newAttribute, CustomAttributeParameterKind.Field, 0)));
5858
f.CustomAttributes.Add(newAttribute);
5959
}
6060
}
@@ -87,12 +87,12 @@ private static void InjectAddressAttribute(ApplicationAnalysisContext appContext
8787

8888
if (!_useEzDiffMode)
8989
{
90-
newAttribute.Fields.Add(new(rvaField, new CustomAttributePrimitiveParameter($"0x{m.Definition.Rva:X}")));
90+
newAttribute.Fields.Add(new(rvaField, new CustomAttributePrimitiveParameter($"0x{m.Definition.Rva:X}", newAttribute, CustomAttributeParameterKind.Field, 0)));
9191
if (appContext.Binary.TryMapVirtualAddressToRaw(m.UnderlyingPointer, out var offset))
92-
newAttribute.Fields.Add(new(offsetField, new CustomAttributePrimitiveParameter($"0x{offset:X}")));
92+
newAttribute.Fields.Add(new(offsetField, new CustomAttributePrimitiveParameter($"0x{offset:X}", newAttribute, CustomAttributeParameterKind.Field, 1)));
9393
}
9494

95-
newAttribute.Fields.Add(new(lengthField, new CustomAttributePrimitiveParameter($"0x{m.RawBytes.Length:X}")));
95+
newAttribute.Fields.Add(new(lengthField, new CustomAttributePrimitiveParameter($"0x{m.RawBytes.Length:X}", newAttribute, CustomAttributeParameterKind.Field, newAttribute.Fields.Count)));
9696
m.CustomAttributes.Add(newAttribute);
9797
}
9898
}
@@ -125,7 +125,7 @@ private static void InjectTokenAttribute(ApplicationAnalysisContext appContext)
125125
return;
126126

127127
var newAttribute = new AnalyzedCustomAttribute(tokenConstructor);
128-
newAttribute.Fields.Add(new(tokenField, new CustomAttributePrimitiveParameter($"0x{context.Token:X}")));
128+
newAttribute.Fields.Add(new(tokenField, new CustomAttributePrimitiveParameter($"0x{context.Token:X}", newAttribute, CustomAttributeParameterKind.Field, 0)));
129129
context.CustomAttributes.Add(newAttribute);
130130
});
131131
}
@@ -210,12 +210,12 @@ private static void ProcessCustomAttributesForContext(HasCustomAttributes contex
210210
offsetInBinary = 0;
211211

212212
//Add the 3 fields to the replacement attribute
213-
replacementAttribute.Fields.Add(new(nameField, new CustomAttributePrimitiveParameter(attribute.Constructor.DeclaringType!.Name)));
214-
replacementAttribute.Fields.Add(new(rvaField, new CustomAttributePrimitiveParameter($"0x{generatorRva:X}")));
215-
replacementAttribute.Fields.Add(new(offsetField, new CustomAttributePrimitiveParameter($"0x{offsetInBinary:X}")));
213+
replacementAttribute.Fields.Add(new(nameField, new CustomAttributePrimitiveParameter(attribute.Constructor.DeclaringType!.Name, replacementAttribute, CustomAttributeParameterKind.Field, 0)));
214+
replacementAttribute.Fields.Add(new(rvaField, new CustomAttributePrimitiveParameter($"0x{generatorRva:X}", replacementAttribute, CustomAttributeParameterKind.Field, 1)));
215+
replacementAttribute.Fields.Add(new(offsetField, new CustomAttributePrimitiveParameter($"0x{offsetInBinary:X}", replacementAttribute, CustomAttributeParameterKind.Field, 2)));
216216

217217
//Replace the original attribute with the replacement attribute
218218
context.CustomAttributes[index] = replacementAttribute;
219219
}
220220
}
221-
}
221+
}

Cpp2IL.Core/Model/CustomAttributes/BaseCustomAttributeParameter.cs

+12-1
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,16 @@ namespace Cpp2IL.Core.Model.CustomAttributes;
55

66
public abstract class BaseCustomAttributeParameter
77
{
8+
public AnalyzedCustomAttribute Owner { get; }
9+
public CustomAttributeParameterKind Kind { get; }
10+
public int Index { get; }
11+
12+
protected BaseCustomAttributeParameter(AnalyzedCustomAttribute owner, CustomAttributeParameterKind kind, int index)
13+
{
14+
Owner = owner;
15+
Kind = kind;
16+
Index = index;
17+
}
18+
819
public abstract void ReadFromV29Blob(BinaryReader reader, ApplicationAnalysisContext context);
9-
}
20+
}

Cpp2IL.Core/Model/CustomAttributes/CustomAttributeArrayParameter.cs

+8-2
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,15 @@ public class CustomAttributeArrayParameter : BaseCustomAttributeParameter
2424
{
2525
public bool IsNullArray;
2626
public Il2CppType? EnumType;
27+
2728
public Il2CppTypeEnum ArrType;
29+
2830
public List<BaseCustomAttributeParameter> ArrayElements = new();
2931

32+
public CustomAttributeArrayParameter(AnalyzedCustomAttribute owner, CustomAttributeParameterKind kind, int index) : base(owner, kind, index)
33+
{
34+
}
35+
3036
public override void ReadFromV29Blob(BinaryReader reader, ApplicationAnalysisContext context)
3137
{
3238
var arrLength = reader.BaseStream.ReadUnityCompressedInt();
@@ -63,7 +69,7 @@ public override void ReadFromV29Blob(BinaryReader reader, ApplicationAnalysisCon
6369
thisType = (Il2CppTypeEnum) reader.ReadByte();
6470

6571
//ConstructParameterForType will handle reading the enum type
66-
var arrayElement = V29AttributeUtils.ConstructParameterForType(reader, context, thisType);
72+
var arrayElement = V29AttributeUtils.ConstructParameterForType(reader, context, thisType, Owner, CustomAttributeParameterKind.ArrayElement, i);
6773

6874
arrayElement.ReadFromV29Blob(reader, context);
6975

@@ -82,4 +88,4 @@ public override string ToString()
8288

8389
return $"new {arrType}[] {{{string.Join(", ", ArrayElements.Select(x => x.ToString()))}}}]";
8490
}
85-
}
91+
}

Cpp2IL.Core/Model/CustomAttributes/CustomAttributeEnumParameter.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ public class CustomAttributeEnumParameter : BaseCustomAttributeParameter
1111
public readonly Il2CppType UnderlyingPrimitiveType;
1212
public readonly CustomAttributePrimitiveParameter UnderlyingPrimitiveParameter;
1313

14-
public CustomAttributeEnumParameter(Il2CppType enumType, ApplicationAnalysisContext context)
14+
public CustomAttributeEnumParameter(Il2CppType enumType, ApplicationAnalysisContext context, AnalyzedCustomAttribute owner, CustomAttributeParameterKind kind, int index) : base(owner, kind, index)
1515
{
1616
EnumType = enumType;
1717
var enumTypeDef = EnumType.AsClass();
1818
UnderlyingPrimitiveType = enumTypeDef.EnumUnderlyingType;
19-
UnderlyingPrimitiveParameter = new(UnderlyingPrimitiveType.Type);
19+
UnderlyingPrimitiveParameter = new(UnderlyingPrimitiveType.Type, owner, kind, index);
2020
}
2121

2222
public Il2CppTypeEnum GetTypeByte() => UnderlyingPrimitiveType.Type;
@@ -32,4 +32,4 @@ public override string ToString()
3232

3333
return UnderlyingPrimitiveParameter.ToString();
3434
}
35-
}
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
namespace Cpp2IL.Core.Model.CustomAttributes;
2+
3+
public enum CustomAttributeParameterKind
4+
{
5+
ConstructorParam,
6+
Field,
7+
Property,
8+
ArrayElement
9+
}

Cpp2IL.Core/Model/CustomAttributes/CustomAttributePrimitiveParameter.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@ public class CustomAttributePrimitiveParameter : BaseCustomAttributeParameter
1616
public readonly Il2CppTypeEnum PrimitiveType;
1717
public IConvertible? PrimitiveValue;
1818

19-
public CustomAttributePrimitiveParameter(Il2CppTypeEnum primitiveType)
19+
public CustomAttributePrimitiveParameter(Il2CppTypeEnum primitiveType, AnalyzedCustomAttribute owner, CustomAttributeParameterKind kind, int index) : base(owner, kind, index)
2020
{
2121
PrimitiveType = primitiveType;
2222
}
2323

24-
public CustomAttributePrimitiveParameter(IConvertible value)
24+
public CustomAttributePrimitiveParameter(IConvertible value, AnalyzedCustomAttribute owner, CustomAttributeParameterKind kind, int index) : base(owner, kind, index)
2525
{
2626
PrimitiveValue = value;
2727

@@ -100,4 +100,4 @@ public override string ToString()
100100

101101
return PrimitiveValue?.ToString(CultureInfo.InvariantCulture) ?? "null";
102102
}
103-
}
103+
}

Cpp2IL.Core/Model/CustomAttributes/CustomAttributeTypeParameter.cs

+6-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ namespace Cpp2IL.Core.Model.CustomAttributes;
1111
public class CustomAttributeTypeParameter : BaseCustomAttributeParameter
1212
{
1313
public Il2CppType? Type;
14+
15+
public CustomAttributeTypeParameter(AnalyzedCustomAttribute owner, CustomAttributeParameterKind kind, int index) : base(owner, kind, index)
16+
{
17+
}
18+
1419
public override void ReadFromV29Blob(BinaryReader reader, ApplicationAnalysisContext context)
1520
{
1621
var typeIndex = reader.BaseStream.ReadUnityCompressedInt();
@@ -29,4 +34,4 @@ public override string ToString()
2934

3035
return $"typeof({Type.AsClass().Name})";
3136
}
32-
}
37+
}

0 commit comments

Comments
 (0)