Skip to content

Commit

Permalink
BUGFIX: Make LPArrayMarshalDescriptor::ArrayElementType nullable.
Browse files Browse the repository at this point in the history
  • Loading branch information
Washi1337 committed Nov 13, 2022
1 parent 545a5e9 commit d9ef330
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ public class LPArrayMarshalDescriptor : MarshalDescriptor
/// </remarks>
public static LPArrayMarshalDescriptor FromReader(ref BinaryStreamReader reader)
{
var descriptor = new LPArrayMarshalDescriptor((NativeType) reader.ReadByte());
var descriptor = new LPArrayMarshalDescriptor();

if (!reader.CanRead(sizeof(byte)))
return descriptor;
descriptor.ArrayElementType = (NativeType) reader.ReadByte();

if (!reader.TryReadCompressedUInt32(out uint value))
return descriptor;
Expand All @@ -34,11 +38,15 @@ public static LPArrayMarshalDescriptor FromReader(ref BinaryStreamReader reader)
return descriptor;
}

public LPArrayMarshalDescriptor()
{
}

/// <summary>
/// Creates a new instance of the <see cref="LPArrayMarshalDescriptor"/> class.
/// </summary>
/// <param name="arrayElementType">The type of elements stored in the array.</param>
public LPArrayMarshalDescriptor(NativeType arrayElementType)
public LPArrayMarshalDescriptor(NativeType? arrayElementType)
{
ArrayElementType = arrayElementType;
}
Expand All @@ -49,7 +57,7 @@ public LPArrayMarshalDescriptor(NativeType arrayElementType)
/// <summary>
/// Gets the type of elements stored in the array.
/// </summary>
public NativeType ArrayElementType
public NativeType? ArrayElementType
{
get;
set;
Expand Down Expand Up @@ -86,20 +94,22 @@ public LPArrayFlags? Flags
protected override void WriteContents(in BlobSerializationContext context)
{
var writer = context.Writer;

writer.WriteByte((byte) NativeType);

if (!ArrayElementType.HasValue)
return;
writer.WriteByte((byte) ArrayElementType);

if (ParameterIndex.HasValue)
{
writer.WriteCompressedUInt32((uint) ParameterIndex.Value);
if (NumberOfElements.HasValue)
{
writer.WriteCompressedUInt32((uint) NumberOfElements.Value);
if (Flags.HasValue)
writer.WriteCompressedUInt32((uint) Flags.Value);
}
}
if (!ParameterIndex.HasValue)
return;
writer.WriteCompressedUInt32((uint) ParameterIndex.Value);

if (!NumberOfElements.HasValue)
return;
writer.WriteCompressedUInt32((uint) NumberOfElements.Value);

if (Flags.HasValue)
writer.WriteCompressedUInt32((uint) Flags.Value);
}
}
}
80 changes: 47 additions & 33 deletions test/AsmResolver.DotNet.Tests/Signatures/MarshalDescriptorTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,24 @@ public void PersistentSimpleMarshaller()
{
var method = LookupMethod(nameof(PlatformInvoke.SimpleMarshaller));
var newMethod = RebuildAndLookup(method);
Assert.Equal(method.Parameters[0].Definition.MarshalDescriptor.NativeType,
Assert.Equal(method.Parameters[0].Definition.MarshalDescriptor.NativeType,
newMethod.Parameters[0].Definition.MarshalDescriptor.NativeType);
}


[Fact]
public void PersistentLPArrayWithoutElementType()
{
var method = LookupMethod(nameof(PlatformInvoke.LPArrayFixedSizeMarshaller));
var originalMarshaller = (LPArrayMarshalDescriptor) method.Parameters[0].Definition!.MarshalDescriptor!;
originalMarshaller.ArrayElementType = null;

var newMethod = RebuildAndLookup(method);
var newArrayMarshaller = Assert.IsAssignableFrom<LPArrayMarshalDescriptor>(
newMethod.Parameters[0].Definition!.MarshalDescriptor);

Assert.Null(newArrayMarshaller.ArrayElementType);
}

[Fact]
public void ReadLPArrayMarshallerWithFixedSize()
{
Expand All @@ -85,7 +99,7 @@ public void PersistentLPArrayMarshallerWithFixedSize()
{
var method = LookupMethod(nameof(PlatformInvoke.LPArrayFixedSizeMarshaller));
var originalMarshaller = (LPArrayMarshalDescriptor) method.Parameters[0].Definition.MarshalDescriptor;

var newMethod = RebuildAndLookup(method);
var newMarshaller = newMethod.Parameters[0].Definition.MarshalDescriptor;
Assert.IsAssignableFrom<LPArrayMarshalDescriptor>(newMarshaller);
Expand All @@ -110,7 +124,7 @@ public void PersistentLPArrayMarshallerWithVariableSize()
{
var method = LookupMethod(nameof(PlatformInvoke.LPArrayVariableSizeMarshaller));
var originalMarshaller = (LPArrayMarshalDescriptor) method.Parameters[0].Definition.MarshalDescriptor;

var newMethod = RebuildAndLookup(method);
var marshaller = newMethod.Parameters[0].Definition.MarshalDescriptor;
Assert.IsAssignableFrom<LPArrayMarshalDescriptor>(marshaller);
Expand All @@ -135,7 +149,7 @@ public void PersistentSafeArrayMarshaller()
{
var method = LookupMethod(nameof(PlatformInvoke.SafeArrayMarshaller));
var originalMarshaller = (SafeArrayMarshalDescriptor) method.Parameters[0].Definition.MarshalDescriptor;

var newMethod = RebuildAndLookup(method);
var marshaller = newMethod.Parameters[0].Definition.MarshalDescriptor;
Assert.IsAssignableFrom<SafeArrayMarshalDescriptor>(marshaller);
Expand All @@ -160,7 +174,7 @@ public void PersistentSafeArrayMarshallerWithSubType()
{
var method = LookupMethod(nameof(PlatformInvoke.SafeArrayMarshallerWithSubType));
var originalMarshaller = (SafeArrayMarshalDescriptor) method.Parameters[0].Definition.MarshalDescriptor;

var newMethod = RebuildAndLookup(method);
var marshaller = newMethod.Parameters[0].Definition.MarshalDescriptor;
Assert.IsAssignableFrom<SafeArrayMarshalDescriptor>(marshaller);
Expand All @@ -186,7 +200,7 @@ public void PersistentSafeArrayMarshallerWithUserDefinedSubType()
{
var method = LookupMethod(nameof(PlatformInvoke.SafeArrayMarshallerWithUserSubType));
var originalMarshaller = (SafeArrayMarshalDescriptor) method.Parameters[0].Definition.MarshalDescriptor;

var newMethod = RebuildAndLookup(method);
var marshaller = newMethod.Parameters[0].Definition.MarshalDescriptor;
Assert.IsAssignableFrom<SafeArrayMarshalDescriptor>(marshaller);
Expand All @@ -195,15 +209,15 @@ public void PersistentSafeArrayMarshallerWithUserDefinedSubType()
Assert.NotNull(arrayMarshaller.UserDefinedSubType);
Assert.Equal(originalMarshaller.UserDefinedSubType.Name, arrayMarshaller.UserDefinedSubType.Name);
}

[Fact]
public void ReadFixedArrayMarshaller()
{
var field = LookupField(nameof(Marshalling.FixedArrayMarshaller));
var marshaller = field.MarshalDescriptor;
Assert.IsAssignableFrom<FixedArrayMarshalDescriptor>(marshaller);
}

[Fact]
public void PersistentFixedArrayMarshaller()
{
Expand All @@ -212,18 +226,18 @@ public void PersistentFixedArrayMarshaller()
var marshaller = newField.MarshalDescriptor;
Assert.IsAssignableFrom<FixedArrayMarshalDescriptor>(marshaller);
}

[Fact]
public void ReadFixedArrayMarshallerWithFixedSizeSpecifier()
{
var field = LookupField(nameof(Marshalling.FixedArrayMarshallerWithFixedSize));
var marshaller = field.MarshalDescriptor;
Assert.IsAssignableFrom<FixedArrayMarshalDescriptor>(marshaller);

var arrayMarshaller = (FixedArrayMarshalDescriptor) marshaller;
Assert.Equal(10, arrayMarshaller.Size);
}

[Fact]
public void PersistentFixedArrayMarshallerWithFixedSizeSpecifier()
{
Expand All @@ -233,33 +247,33 @@ public void PersistentFixedArrayMarshallerWithFixedSizeSpecifier()
var newField = RebuildAndLookup(field);
var marshaller = newField.MarshalDescriptor;
Assert.IsAssignableFrom<FixedArrayMarshalDescriptor>(marshaller);

var arrayMarshaller = (FixedArrayMarshalDescriptor) marshaller;
Assert.Equal(originalMarshaller.Size, arrayMarshaller.Size);
}

[Fact]
public void ReadFixedArrayMarshallerWithFixedSizeSpecifierAndArrayType()
{
var field = LookupField(nameof(Marshalling.FixedArrayMarshallerWithFixedSizeAndArrayType));
var marshaller = field.MarshalDescriptor;
Assert.IsAssignableFrom<FixedArrayMarshalDescriptor>(marshaller);

var arrayMarshaller = (FixedArrayMarshalDescriptor) marshaller;
Assert.Equal(10, arrayMarshaller.Size);
Assert.Equal(NativeType.U1, arrayMarshaller.ArrayElementType);
}

[Fact]
public void PersistentFixedArrayMarshallerWithFixedSizeSpecifierAndArrayType()
{
var field = LookupField(nameof(Marshalling.FixedArrayMarshallerWithFixedSizeAndArrayType));
var originalMarshaller = (FixedArrayMarshalDescriptor) field.MarshalDescriptor;

var newField = RebuildAndLookup(field);
var marshaller = newField.MarshalDescriptor;
Assert.IsAssignableFrom<FixedArrayMarshalDescriptor>(marshaller);

var arrayMarshaller = (FixedArrayMarshalDescriptor) marshaller;
Assert.Equal(originalMarshaller.Size, arrayMarshaller.Size);
Assert.Equal(originalMarshaller.ArrayElementType, arrayMarshaller.ArrayElementType);
Expand All @@ -271,7 +285,7 @@ public void ReadCustomMarshallerType()
var field = LookupField(nameof(Marshalling.CustomMarshallerWithCustomType));
var marshaller = field.MarshalDescriptor;
Assert.IsAssignableFrom<CustomMarshalDescriptor>(marshaller);

var customMarshaller = (CustomMarshalDescriptor) marshaller;
Assert.Equal(nameof(Marshalling), customMarshaller.MarshalType.Name);
}
Expand All @@ -281,11 +295,11 @@ public void PersistentCustomMarshallerType()
{
var field = LookupField(nameof(Marshalling.CustomMarshallerWithCustomType));
var originalMarshaller = (CustomMarshalDescriptor) field.MarshalDescriptor;

var newField = RebuildAndLookup(field);
var marshaller = newField.MarshalDescriptor;
Assert.IsAssignableFrom<CustomMarshalDescriptor>(marshaller);

var customMarshaller = (CustomMarshalDescriptor) marshaller;
Assert.Equal(originalMarshaller.MarshalType.Name, customMarshaller.MarshalType.Name);
}
Expand All @@ -296,7 +310,7 @@ public void ReadCustomMarshallerTypeWithCookie()
var field = LookupField(nameof(Marshalling.CustomMarshallerWithCustomTypeAndCookie));
var marshaller = field.MarshalDescriptor;
Assert.IsAssignableFrom<CustomMarshalDescriptor>(marshaller);

var customMarshaller = (CustomMarshalDescriptor) marshaller;
Assert.Equal(nameof(Marshalling), customMarshaller.MarshalType.Name);
Assert.Equal("abc", customMarshaller.Cookie);
Expand All @@ -307,11 +321,11 @@ public void PersistentCustomMarshallerTypeWithCookie()
{
var field = LookupField(nameof(Marshalling.CustomMarshallerWithCustomTypeAndCookie));
var originalMarshaller = (CustomMarshalDescriptor) field.MarshalDescriptor;

var newField = RebuildAndLookup(field);
var marshaller = newField.MarshalDescriptor;
Assert.IsAssignableFrom<CustomMarshalDescriptor>(marshaller);

var customMarshaller = (CustomMarshalDescriptor) marshaller;
Assert.Equal(originalMarshaller.MarshalType.Name, customMarshaller.MarshalType.Name);
Assert.Equal(originalMarshaller.Cookie, customMarshaller.Cookie);
Expand All @@ -323,7 +337,7 @@ public void ReadFixedSysString()
var field = LookupField(nameof(Marshalling.FixedSysString));
var marshaller = field.MarshalDescriptor;
Assert.IsAssignableFrom<FixedSysStringMarshalDescriptor>(marshaller);

var stringMarshaller = (FixedSysStringMarshalDescriptor) marshaller;
Assert.Equal(123, stringMarshaller.Size);
}
Expand All @@ -333,11 +347,11 @@ public void PersistentFixedSysString()
{
var field = LookupField(nameof(Marshalling.FixedSysString));
var originalMarshaller = (FixedSysStringMarshalDescriptor) field.MarshalDescriptor;

var newField = RebuildAndLookup(field);
var marshaller = newField.MarshalDescriptor;
Assert.IsAssignableFrom<FixedSysStringMarshalDescriptor>(marshaller);

var stringMarshaller = (FixedSysStringMarshalDescriptor) marshaller;
Assert.Equal(originalMarshaller.Size, stringMarshaller.Size);
}
Expand All @@ -348,7 +362,7 @@ public void ReadComInterface()
var method = LookupMethod(nameof(PlatformInvoke.ComInterface));
var marshaller = method.Parameters[0].Definition.MarshalDescriptor;
Assert.IsAssignableFrom<ComInterfaceMarshalDescriptor>(marshaller);

var comMarshaller = (ComInterfaceMarshalDescriptor) marshaller;
Assert.Null(comMarshaller.IidParameterIndex);
}
Expand All @@ -361,7 +375,7 @@ public void PersistentComInterface()
var newMethod = RebuildAndLookup(method);
var marshaller = newMethod.Parameters[0].Definition.MarshalDescriptor;
Assert.IsAssignableFrom<ComInterfaceMarshalDescriptor>(marshaller);

var comMarshaller = (ComInterfaceMarshalDescriptor) marshaller;
Assert.Null(comMarshaller.IidParameterIndex);
}
Expand All @@ -372,7 +386,7 @@ public void ReadComInterfaceWithParameterIndex()
var method = LookupMethod(nameof(PlatformInvoke.ComInterfaceWithIidParameter));
var marshaller = method.Parameters[0].Definition.MarshalDescriptor;
Assert.IsAssignableFrom<ComInterfaceMarshalDescriptor>(marshaller);

var comMarshaller = (ComInterfaceMarshalDescriptor) marshaller;
Assert.Equal(1, comMarshaller.IidParameterIndex);
}
Expand All @@ -382,13 +396,13 @@ public void PersistentComInterfaceWithParameterIndex()
{
var method = LookupMethod(nameof(PlatformInvoke.ComInterfaceWithIidParameter));
var originalMarshaller = (ComInterfaceMarshalDescriptor) method.Parameters[0].Definition.MarshalDescriptor;

var newMethod = RebuildAndLookup(method);
var marshaller = newMethod.Parameters[0].Definition.MarshalDescriptor;
Assert.IsAssignableFrom<ComInterfaceMarshalDescriptor>(marshaller);

var comMarshaller = (ComInterfaceMarshalDescriptor) marshaller;
Assert.Equal(originalMarshaller.IidParameterIndex, comMarshaller.IidParameterIndex);
}
}
}
}

0 comments on commit d9ef330

Please sign in to comment.