Skip to content

Commit

Permalink
Core: Fix exception when attempting to serialize null array as CA arg
Browse files Browse the repository at this point in the history
  • Loading branch information
SamboyCoding committed Sep 4, 2022
1 parent 894ab4f commit 9bcf80b
Show file tree
Hide file tree
Showing 10 changed files with 177 additions and 91 deletions.
18 changes: 9 additions & 9 deletions Cpp2IL.Core/CorePlugin/AttributeInjectorProcessingLayer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ private static void InjectFieldOffsetAttribute(ApplicationAnalysisContext appCon
var newAttribute = new AnalyzedCustomAttribute(fieldOffsetConstructor);

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

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

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

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

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

//Replace the original attribute with the replacement attribute
context.CustomAttributes[index] = replacementAttribute;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,16 @@ namespace Cpp2IL.Core.Model.CustomAttributes;

public abstract class BaseCustomAttributeParameter
{
public AnalyzedCustomAttribute Owner { get; }
public CustomAttributeParameterKind Kind { get; }
public int Index { get; }

protected BaseCustomAttributeParameter(AnalyzedCustomAttribute owner, CustomAttributeParameterKind kind, int index)
{
Owner = owner;
Kind = kind;
Index = index;
}

public abstract void ReadFromV29Blob(BinaryReader reader, ApplicationAnalysisContext context);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,15 @@ public class CustomAttributeArrayParameter : BaseCustomAttributeParameter
{
public bool IsNullArray;
public Il2CppType? EnumType;

public Il2CppTypeEnum ArrType;

public List<BaseCustomAttributeParameter> ArrayElements = new();

public CustomAttributeArrayParameter(AnalyzedCustomAttribute owner, CustomAttributeParameterKind kind, int index) : base(owner, kind, index)
{
}

public override void ReadFromV29Blob(BinaryReader reader, ApplicationAnalysisContext context)
{
var arrLength = reader.BaseStream.ReadUnityCompressedInt();
Expand Down Expand Up @@ -63,7 +69,7 @@ public override void ReadFromV29Blob(BinaryReader reader, ApplicationAnalysisCon
thisType = (Il2CppTypeEnum) reader.ReadByte();

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

arrayElement.ReadFromV29Blob(reader, context);

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

return $"new {arrType}[] {{{string.Join(", ", ArrayElements.Select(x => x.ToString()))}}}]";
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ public class CustomAttributeEnumParameter : BaseCustomAttributeParameter
public readonly Il2CppType UnderlyingPrimitiveType;
public readonly CustomAttributePrimitiveParameter UnderlyingPrimitiveParameter;

public CustomAttributeEnumParameter(Il2CppType enumType, ApplicationAnalysisContext context)
public CustomAttributeEnumParameter(Il2CppType enumType, ApplicationAnalysisContext context, AnalyzedCustomAttribute owner, CustomAttributeParameterKind kind, int index) : base(owner, kind, index)
{
EnumType = enumType;
var enumTypeDef = EnumType.AsClass();
UnderlyingPrimitiveType = enumTypeDef.EnumUnderlyingType;
UnderlyingPrimitiveParameter = new(UnderlyingPrimitiveType.Type);
UnderlyingPrimitiveParameter = new(UnderlyingPrimitiveType.Type, owner, kind, index);
}

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

return UnderlyingPrimitiveParameter.ToString();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Cpp2IL.Core.Model.CustomAttributes;

public enum CustomAttributeParameterKind
{
ConstructorParam,
Field,
Property,
ArrayElement
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ public class CustomAttributePrimitiveParameter : BaseCustomAttributeParameter
public readonly Il2CppTypeEnum PrimitiveType;
public IConvertible? PrimitiveValue;

public CustomAttributePrimitiveParameter(Il2CppTypeEnum primitiveType)
public CustomAttributePrimitiveParameter(Il2CppTypeEnum primitiveType, AnalyzedCustomAttribute owner, CustomAttributeParameterKind kind, int index) : base(owner, kind, index)
{
PrimitiveType = primitiveType;
}

public CustomAttributePrimitiveParameter(IConvertible value)
public CustomAttributePrimitiveParameter(IConvertible value, AnalyzedCustomAttribute owner, CustomAttributeParameterKind kind, int index) : base(owner, kind, index)
{
PrimitiveValue = value;

Expand Down Expand Up @@ -100,4 +100,4 @@ public override string ToString()

return PrimitiveValue?.ToString(CultureInfo.InvariantCulture) ?? "null";
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ namespace Cpp2IL.Core.Model.CustomAttributes;
public class CustomAttributeTypeParameter : BaseCustomAttributeParameter
{
public Il2CppType? Type;

public CustomAttributeTypeParameter(AnalyzedCustomAttribute owner, CustomAttributeParameterKind kind, int index) : base(owner, kind, index)
{
}

public override void ReadFromV29Blob(BinaryReader reader, ApplicationAnalysisContext context)
{
var typeIndex = reader.BaseStream.ReadUnityCompressedInt();
Expand All @@ -29,4 +34,4 @@ public override string ToString()

return $"typeof({Type.AsClass().Name})";
}
}
}
Loading

0 comments on commit 9bcf80b

Please sign in to comment.