Skip to content

Commit 66e665f

Browse files
authored
Big-endian test case fixes: System.Reflection (#49693)
* Fix endian assumptions in tests operating on PE headers / IL metadata (this is always encoded in little-endian byte order) * Fix expected result for BlobReader test (always little-endian) * Fix expected results for GUID tests
1 parent cf61dcd commit 66e665f

File tree

6 files changed

+83
-60
lines changed

6 files changed

+83
-60
lines changed

src/libraries/System.Reflection.Emit.ILGeneration/tests/ILGenerator/EmitMethodInfo.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System;
5+
using System.Buffers.Binary;
56
using System.Collections.Generic;
67
using System.Linq;
78
using System.Text;
@@ -38,7 +39,7 @@ public void EmitMethodInfo()
3839
MethodInfo genMethod = type.GetMethod("Get");
3940
byte[] il = genMethod.GetMethodBody().GetILAsByteArray();
4041

41-
int ilMethodMetadataToken = BitConverter.ToInt32(il, 1);
42+
int ilMethodMetadataToken = BinaryPrimitives.ReadInt32LittleEndian(new Span<byte>(il, 1, 4));
4243
MethodBase resolvedMethod = type.Module.ResolveMethod(ilMethodMetadataToken);
4344
Assert.Equal(method, resolvedMethod);
4445
var methodBase = (MethodBase)genMethod.Invoke(null, null);

src/libraries/System.Reflection.Metadata/tests/Metadata/BlobContentIdTests.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,17 +64,17 @@ public void FromHash()
6464
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20));
6565

6666
AssertEx.Equal(new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x48, 0x89, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10 }, id1.Guid.ToByteArray());
67-
AssertEx.Equal(new byte[] { 0x11, 0x12, 0x13, 0x94 }, BitConverter.GetBytes(id1.Stamp));
67+
Assert.Equal(0x94131211u, id1.Stamp);
6868

6969
var id2 = BlobContentId.FromHash(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 });
7070

7171
AssertEx.Equal(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, id2.Guid.ToByteArray());
72-
AssertEx.Equal(new byte[] { 0x00, 0x00, 0x00, 0x80 }, BitConverter.GetBytes(id2.Stamp));
72+
Assert.Equal(0x80000000u, id2.Stamp);
7373

7474
var id3 = BlobContentId.FromHash(new byte[] { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff });
7575

7676
AssertEx.Equal(new byte[] { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x4f, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, id3.Guid.ToByteArray());
77-
AssertEx.Equal(new byte[] { 0xff, 0xff, 0xff, 0xff }, BitConverter.GetBytes(id3.Stamp));
77+
Assert.Equal(0xffffffffu, id3.Stamp);
7878

7979
Assert.Throws<ArgumentNullException>(() => BlobContentId.FromHash(default(ImmutableArray<byte>)));
8080
Assert.Throws<ArgumentNullException>(() => BlobContentId.FromHash(null));

src/libraries/System.Reflection.Metadata/tests/Metadata/Ecma335/MetadataAggregatorTests.cs

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,14 @@ namespace System.Reflection.Metadata.Ecma335.Tests
1010
{
1111
public class MetadataAggregatorTests
1212
{
13-
private static unsafe EnCMapTableReader CreateEncMapTable(int[] tokens)
13+
private static unsafe EnCMapTableReader CreateEncMapTable(byte[] tokens)
1414
{
1515
GCHandle handle = GCHandle.Alloc(tokens, GCHandleType.Pinned);
16-
var block = new MemoryBlock((byte*)handle.AddrOfPinnedObject(), tokens.Length * sizeof(uint));
17-
return new EnCMapTableReader(tokens.Length, block, containingBlockOffset: 0);
16+
var block = new MemoryBlock((byte*)handle.AddrOfPinnedObject(), tokens.Length);
17+
return new EnCMapTableReader(tokens.Length / sizeof(uint), block, containingBlockOffset: 0);
1818
}
1919

20-
private static EnCMapTableReader[] CreateEncMapTables(int[][] tables)
20+
private static EnCMapTableReader[] CreateEncMapTables(byte[][] tables)
2121
{
2222
var result = new EnCMapTableReader[tables.Length];
2323

@@ -47,35 +47,35 @@ public void RowCounts()
4747
{
4848
var encMaps = new[]
4949
{
50-
new[] // Gen1
50+
new byte[] // Gen1
5151
{
52-
0x0100009c,
53-
0x0200002e,
54-
0x0600009e,
55-
0x0600009f,
56-
0x23000011,
52+
0x9c, 0x00, 0x00, 0x01,
53+
0x2e, 0x00, 0x00, 0x02,
54+
0x9e, 0x00, 0x00, 0x06,
55+
0x9f, 0x00, 0x00, 0x06,
56+
0x11, 0x00, 0x00, 0x23,
5757
},
58-
new[] // Gen2
58+
new byte[] // Gen2
5959
{
60-
0x0100009d,
61-
0x06000075,
62-
0x1700001a,
63-
0x18000037,
64-
0x18000038,
65-
0x23000012,
66-
0x23000013,
60+
0x9d, 0x00, 0x00, 0x01,
61+
0x75, 0x00, 0x00, 0x06,
62+
0x1a, 0x00, 0x00, 0x17,
63+
0x37, 0x00, 0x00, 0x18,
64+
0x38, 0x00, 0x00, 0x18,
65+
0x12, 0x00, 0x00, 0x23,
66+
0x13, 0x00, 0x00, 0x23,
6767
},
68-
new[] // Gen3
68+
new byte[] // Gen3
6969
{
70-
0x0100009e,
71-
0x0100009f,
72-
0x06000075,
73-
0x11000031,
74-
0x1700001a,
75-
0x18000039,
76-
0x1800003a,
77-
0x23000014,
78-
0x23000015,
70+
0x9e, 0x00, 0x00, 0x01,
71+
0x9f, 0x00, 0x00, 0x01,
72+
0x75, 0x00, 0x00, 0x06,
73+
0x31, 0x00, 0x00, 0x11,
74+
0x1a, 0x00, 0x00, 0x17,
75+
0x39, 0x00, 0x00, 0x18,
76+
0x3a, 0x00, 0x00, 0x18,
77+
0x14, 0x00, 0x00, 0x23,
78+
0x15, 0x00, 0x00, 0x23,
7979
}
8080
};
8181

src/libraries/System.Reflection.Metadata/tests/Metadata/MetadataReaderTests.cs

Lines changed: 33 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4+
using System.Buffers.Binary;
45
using System.Collections.Generic;
56
using System.IO;
67
using System.Linq;
@@ -203,11 +204,11 @@ public unsafe void InvalidExternalTableMask()
203204
byte[] peImage = (byte[])PortablePdbs.DocumentsPdb.Clone();
204205
GCHandle pinned = GetPinnedPEImage(peImage);
205206

206-
//38654710855 is the external table mask from PortablePdbs.DocumentsPdb
207-
int externalTableMaskIndex = IndexOf(peImage, BitConverter.GetBytes(38654710855), 0);
207+
//0x900001447 is the external table mask from PortablePdbs.DocumentsPdb
208+
int externalTableMaskIndex = IndexOf(peImage, new byte[] { 0x47, 0x14, 0, 0, 9, 0, 0, 0 }, 0);
208209
Assert.NotEqual(externalTableMaskIndex, -1);
209210

210-
Array.Copy(BitConverter.GetBytes(38654710855 + 1), 0, peImage, externalTableMaskIndex, BitConverter.GetBytes(38654710855 + 1).Length);
211+
Array.Copy(new byte[] { 0x48, 0x14, 0, 0, 9, 0, 0, 0 }, 0, peImage, externalTableMaskIndex, 8);
211212
Assert.Throws<BadImageFormatException>(() => new MetadataReader((byte*)pinned.AddrOfPinnedObject(), peImage.Length));
212213
}
213214

@@ -245,30 +246,30 @@ public unsafe void InvalidMetaDataTableHeaders()
245246
GCHandle pinned = GetPinnedPEImage(peImage);
246247
PEHeaders headers = new PEHeaders(new MemoryStream(peImage));
247248

248-
//1392 is the remaining bytes from NetModule.AppCS
249-
int remainingBytesIndex = IndexOf(peImage, BitConverter.GetBytes(1392), headers.MetadataStartOffset);
249+
//0x0570 is the remaining bytes from NetModule.AppCS
250+
int remainingBytesIndex = IndexOf(peImage, new byte[] { 0x70, 0x05, 0, 0 }, headers.MetadataStartOffset);
250251
Assert.NotEqual(remainingBytesIndex, -1);
251-
//14057656686423 is the presentTables from NetModule.AppCS, must be after remainingBytesIndex
252-
int presentTablesIndex = IndexOf(peImage, BitConverter.GetBytes(14057656686423), headers.MetadataStartOffset + remainingBytesIndex);
252+
//0xcc90da21757 is the presentTables from NetModule.AppCS, must be after remainingBytesIndex
253+
int presentTablesIndex = IndexOf(peImage, new byte[] { 0x57, 0x17, 0xa2, 0x0d, 0xc9, 0x0c, 0, 0 }, headers.MetadataStartOffset + remainingBytesIndex);
253254
Assert.NotEqual(presentTablesIndex, -1);
254255

255256
//Set this.ModuleTable.NumberOfRows to 0
256-
Array.Copy(BitConverter.GetBytes((ulong)0), 0, peImage, presentTablesIndex + remainingBytesIndex + headers.MetadataStartOffset + 16, BitConverter.GetBytes((ulong)0).Length);
257+
Array.Copy(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 }, 0, peImage, presentTablesIndex + remainingBytesIndex + headers.MetadataStartOffset + 16, 8);
257258
Assert.Throws<BadImageFormatException>(() => new MetadataReader((byte*)pinned.AddrOfPinnedObject() + headers.MetadataStartOffset, headers.MetadataSize));
258259
//set row counts greater than TokenTypeIds.RIDMask
259-
Array.Copy(BitConverter.GetBytes((ulong)16777216), 0, peImage, presentTablesIndex + remainingBytesIndex + headers.MetadataStartOffset + 16, BitConverter.GetBytes((ulong)16777216).Length);
260+
Array.Copy(new byte[] { 0, 0, 1, 0 }, 0, peImage, presentTablesIndex + remainingBytesIndex + headers.MetadataStartOffset + 16, 4);
260261
Assert.Throws<BadImageFormatException>(() => new MetadataReader((byte*)pinned.AddrOfPinnedObject() + headers.MetadataStartOffset, headers.MetadataSize));
261262
//set remaining bytes smaller than required for row counts.
262-
Array.Copy(BitConverter.GetBytes(25), 0, peImage, remainingBytesIndex + headers.MetadataStartOffset, BitConverter.GetBytes(25).Length);
263+
Array.Copy(new byte[] { 25, 0, 0, 0 }, 0, peImage, remainingBytesIndex + headers.MetadataStartOffset, 4);
263264
Assert.Throws<BadImageFormatException>(() => new MetadataReader((byte*)pinned.AddrOfPinnedObject() + headers.MetadataStartOffset, headers.MetadataSize));
264-
//14057656686424 is a value to make (presentTables & ~validTables) != 0 but not (presentTables & (ulong)(TableMask.PtrTables | TableMask.EnCMap)) != 0
265-
Array.Copy(BitConverter.GetBytes((ulong)14057656686424), 0, peImage, presentTablesIndex + remainingBytesIndex + headers.MetadataStartOffset, BitConverter.GetBytes((ulong)14057656686424).Length);
265+
//0xcc90da21758 is a value to make (presentTables & ~validTables) != 0 but not (presentTables & (ulong)(TableMask.PtrTables | TableMask.EnCMap)) != 0
266+
Array.Copy(new byte[] { 0x58, 0x17, 0xa2, 0x0d, 0xc9, 0x0c, 0, 0 }, 0, peImage, presentTablesIndex + remainingBytesIndex + headers.MetadataStartOffset, 8);
266267
Assert.Throws<BadImageFormatException>(() => new MetadataReader((byte*)pinned.AddrOfPinnedObject() + headers.MetadataStartOffset, headers.MetadataSize));
267-
//14066246621015 makes (presentTables & ~validTables) != 0 fail
268-
Array.Copy(BitConverter.GetBytes((ulong)14066246621015), 0, peImage, presentTablesIndex + remainingBytesIndex + headers.MetadataStartOffset, BitConverter.GetBytes((ulong)14066246621015).Length);
268+
//0xccb0da21757 makes (presentTables & ~validTables) != 0 fail
269+
Array.Copy(new byte[] { 0x57, 0x17, 0xa2, 0x0d, 0xcb, 0x0c, 0, 0 }, 0, peImage, presentTablesIndex + remainingBytesIndex + headers.MetadataStartOffset, 8);
269270
Assert.Throws<BadImageFormatException>(() => new MetadataReader((byte*)pinned.AddrOfPinnedObject() + headers.MetadataStartOffset, headers.MetadataSize));
270271
//set remaining bytes smaller than MetadataStreamConstants.SizeOfMetadataTableHeader
271-
Array.Copy(BitConverter.GetBytes(1), 0, peImage, remainingBytesIndex + headers.MetadataStartOffset, BitConverter.GetBytes(1).Length);
272+
Array.Copy(new byte[] { 1, 0, 0, 0 }, 0, peImage, remainingBytesIndex + headers.MetadataStartOffset, 4);
272273
Assert.Throws<BadImageFormatException>(() => new MetadataReader((byte*)pinned.AddrOfPinnedObject() + headers.MetadataStartOffset, headers.MetadataSize));
273274
}
274275

@@ -3033,18 +3034,25 @@ private static unsafe byte[] ObfuscateWithExtraData(byte[] unobfuscated, bool se
30333034
Array.Copy(unobfuscated, obfuscated, offsetToModuleTable);
30343035
Array.Copy(unobfuscated, offsetToModuleTable, obfuscated, offsetToModuleTable + sizeOfExtraData, unobfuscated.Length - offsetToModuleTable);
30353036

3036-
fixed (byte* ptr = obfuscated)
3037-
{
3038-
// increase size of metadata
3039-
*(int*)(ptr + offsetToMetadataSize) += sizeOfExtraData;
3037+
// increase size of metadata
3038+
Span<byte> MetadataSizeSpan = new Span<byte>(obfuscated, offsetToMetadataSize, 4);
3039+
uint MetadataSize = BinaryPrimitives.ReadUInt32LittleEndian(MetadataSizeSpan);
3040+
BinaryPrimitives.WriteUInt32LittleEndian(MetadataSizeSpan, MetadataSize + sizeOfExtraData);
30403041

3041-
// increase size of table stream
3042-
*(int*)(ptr + streamHeaders[tableStreamIndex].OffsetToSize) += sizeOfExtraData;
3042+
// increase size of table stream
3043+
Span<byte> TableStreamSpan = new Span<byte>(obfuscated, streamHeaders[tableStreamIndex].OffsetToSize, 4);
3044+
uint TableStreamSize = BinaryPrimitives.ReadUInt32LittleEndian(TableStreamSpan);
3045+
BinaryPrimitives.WriteUInt32LittleEndian(TableStreamSpan, TableStreamSize + sizeOfExtraData);
30433046

3044-
// adjust offset of any streams that follow it
3045-
for (int i = 0; i < streamHeaders.Length; i++)
3046-
if (streamHeaders[i].Offset > streamHeaders[tableStreamIndex].Offset)
3047-
*(int*)(ptr + streamHeaders[i].OffsetToOffset) += sizeOfExtraData;
3047+
// adjust offset of any streams that follow it
3048+
for (int i = 0; i < streamHeaders.Length; i++)
3049+
{
3050+
if (streamHeaders[i].Offset > streamHeaders[tableStreamIndex].Offset)
3051+
{
3052+
Span<byte> OffsetSpan = new Span<byte>(obfuscated, streamHeaders[i].OffsetToOffset, 4);
3053+
uint Offset = BinaryPrimitives.ReadUInt32LittleEndian(OffsetSpan);
3054+
BinaryPrimitives.WriteUInt32LittleEndian(OffsetSpan, Offset + sizeOfExtraData);
3055+
}
30483056
}
30493057

30503058
// write non-zero "extra data" to make sure so that our assertion of leading Module.Generation == 0

src/libraries/System.Reflection.Metadata/tests/Metadata/TagToTokenTests.cs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,25 @@ private IEnumerable<XxxTag> GetTags()
6161
Assert.Contains(vector.FieldType, new[] { typeof(uint), typeof(ulong) });
6262
if (vector.FieldType == typeof(uint))
6363
{
64-
return BitConverter.GetBytes((uint)vector.GetValue(null)).Select(t => (uint)t << TokenTypeIds.RowIdBitCount).ToArray();
64+
uint value = (uint)vector.GetValue(null);
65+
uint[] ret = new uint[4];
66+
for (uint i = 0; i < 4; i++)
67+
{
68+
ret[i] = ((uint)(byte)value) << TokenTypeIds.RowIdBitCount;
69+
value >>= 8;
70+
}
71+
return ret;
6572
}
6673
else
6774
{
68-
return BitConverter.GetBytes((ulong)vector.GetValue(null)).Select(t => (uint)t << TokenTypeIds.RowIdBitCount).ToArray();
75+
ulong value = (ulong)vector.GetValue(null);
76+
uint[] ret = new uint[8];
77+
for (uint i = 0; i < 8; i++)
78+
{
79+
ret[i] = ((uint)(byte)value) << TokenTypeIds.RowIdBitCount;
80+
value >>= 8;
81+
}
82+
return ret;
6983
}
7084
},
7185

src/libraries/System.Reflection.Metadata/tests/Utilities/BlobReaderTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ public unsafe void ReadFromMemoryReader()
307307

308308
reader.Reset();
309309
Assert.Equal(0, reader.Offset);
310-
Assert.Equal(BitConverter.ToDouble(buffer2, 0), reader.ReadDouble());
310+
Assert.Equal(BitConverter.Int64BitsToDouble(0x0807060504030201L), reader.ReadDouble());
311311
}
312312
}
313313

0 commit comments

Comments
 (0)