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

github.com/dotnet/runtime.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlrich Weigand <ulrich.weigand@de.ibm.com>2021-03-19 15:00:15 +0300
committerGitHub <noreply@github.com>2021-03-19 15:00:15 +0300
commitc37395208c35770a0203785b886f990ee5c12fcd (patch)
tree65d79a02aa54177e4fc449acc564bb441b69cea4 /src/libraries
parent3042a6657b1ab38f39c9826c959669a811532230 (diff)
Big-endian fix: GUID handling (#49813)
* Fix Utf8Formatter.Guid on big-endian systems (first three fields are stored in native byte order, not always little-endian) * Use Guid constructor in BlobContentId.FromHash to remove endian-dependent code accessing the structure directly
Diffstat (limited to 'src/libraries')
-rw-r--r--src/libraries/System.Private.CoreLib/src/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Guid.cs44
-rw-r--r--src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/BlobContentId.cs25
2 files changed, 51 insertions, 18 deletions
diff --git a/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Guid.cs b/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Guid.cs
index 4b366f70908..888f5ab51d5 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Guid.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Guid.cs
@@ -109,7 +109,7 @@ namespace System.Buffers.Text
DecomposedGuid guidAsBytes = default;
guidAsBytes.Guid = value;
- // When a GUID is blitted, the first three components are little-endian, and the last component is big-endian.
+ // When a GUID is blitted, the first three components are native-endian, and the last component is big-endian.
// The line below forces the JIT to hoist the bounds check for the following segment.
// The JIT will optimize away the read, but it cannot optimize away the bounds check
@@ -117,10 +117,20 @@ namespace System.Buffers.Text
// We use 8 instead of 7 so that we also capture the dash if we're asked to insert one.
{ _ = destination[8]; }
- HexConverter.ToBytesBuffer(guidAsBytes.Byte03, destination, 0, HexConverter.Casing.Lower);
- HexConverter.ToBytesBuffer(guidAsBytes.Byte02, destination, 2, HexConverter.Casing.Lower);
- HexConverter.ToBytesBuffer(guidAsBytes.Byte01, destination, 4, HexConverter.Casing.Lower);
- HexConverter.ToBytesBuffer(guidAsBytes.Byte00, destination, 6, HexConverter.Casing.Lower);
+ if (BitConverter.IsLittleEndian)
+ {
+ HexConverter.ToBytesBuffer(guidAsBytes.Byte03, destination, 0, HexConverter.Casing.Lower);
+ HexConverter.ToBytesBuffer(guidAsBytes.Byte02, destination, 2, HexConverter.Casing.Lower);
+ HexConverter.ToBytesBuffer(guidAsBytes.Byte01, destination, 4, HexConverter.Casing.Lower);
+ HexConverter.ToBytesBuffer(guidAsBytes.Byte00, destination, 6, HexConverter.Casing.Lower);
+ }
+ else
+ {
+ HexConverter.ToBytesBuffer(guidAsBytes.Byte00, destination, 0, HexConverter.Casing.Lower);
+ HexConverter.ToBytesBuffer(guidAsBytes.Byte01, destination, 2, HexConverter.Casing.Lower);
+ HexConverter.ToBytesBuffer(guidAsBytes.Byte02, destination, 4, HexConverter.Casing.Lower);
+ HexConverter.ToBytesBuffer(guidAsBytes.Byte03, destination, 6, HexConverter.Casing.Lower);
+ }
if (flags < 0 /* use dash? */)
{
@@ -133,8 +143,16 @@ namespace System.Buffers.Text
}
{ _ = destination[4]; }
- HexConverter.ToBytesBuffer(guidAsBytes.Byte05, destination, 0, HexConverter.Casing.Lower);
- HexConverter.ToBytesBuffer(guidAsBytes.Byte04, destination, 2, HexConverter.Casing.Lower);
+ if (BitConverter.IsLittleEndian)
+ {
+ HexConverter.ToBytesBuffer(guidAsBytes.Byte05, destination, 0, HexConverter.Casing.Lower);
+ HexConverter.ToBytesBuffer(guidAsBytes.Byte04, destination, 2, HexConverter.Casing.Lower);
+ }
+ else
+ {
+ HexConverter.ToBytesBuffer(guidAsBytes.Byte04, destination, 0, HexConverter.Casing.Lower);
+ HexConverter.ToBytesBuffer(guidAsBytes.Byte05, destination, 2, HexConverter.Casing.Lower);
+ }
if (flags < 0 /* use dash? */)
{
@@ -147,8 +165,16 @@ namespace System.Buffers.Text
}
{ _ = destination[4]; }
- HexConverter.ToBytesBuffer(guidAsBytes.Byte07, destination, 0, HexConverter.Casing.Lower);
- HexConverter.ToBytesBuffer(guidAsBytes.Byte06, destination, 2, HexConverter.Casing.Lower);
+ if (BitConverter.IsLittleEndian)
+ {
+ HexConverter.ToBytesBuffer(guidAsBytes.Byte07, destination, 0, HexConverter.Casing.Lower);
+ HexConverter.ToBytesBuffer(guidAsBytes.Byte06, destination, 2, HexConverter.Casing.Lower);
+ }
+ else
+ {
+ HexConverter.ToBytesBuffer(guidAsBytes.Byte06, destination, 0, HexConverter.Casing.Lower);
+ HexConverter.ToBytesBuffer(guidAsBytes.Byte07, destination, 2, HexConverter.Casing.Lower);
+ }
if (flags < 0 /* use dash? */)
{
diff --git a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/BlobContentId.cs b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/BlobContentId.cs
index 270c9112134..0ca5a419f68 100644
--- a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/BlobContentId.cs
+++ b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/BlobContentId.cs
@@ -52,7 +52,7 @@ namespace System.Reflection.Metadata
return FromHash(ImmutableByteArrayInterop.DangerousGetUnderlyingArray(hashCode)!);
}
- public static unsafe BlobContentId FromHash(byte[] hashCode)
+ public static BlobContentId FromHash(byte[] hashCode)
{
const int minHashSize = 20;
@@ -66,16 +66,23 @@ namespace System.Reflection.Metadata
throw new ArgumentException(SR.Format(SR.HashTooShort, minHashSize), nameof(hashCode));
}
- Guid guid = default(Guid);
- byte* guidPtr = (byte*)&guid;
- for (var i = 0; i < BlobUtilities.SizeOfGuid; i++)
- {
- guidPtr[i] = hashCode[i];
- }
+ // extract guid components from input data
+ uint a = ((uint)hashCode[3] << 24 | (uint)hashCode[2] << 16 | (uint)hashCode[1] << 8 | hashCode[0]);
+ ushort b = (ushort)((ushort)hashCode[5] << 8 | (ushort)hashCode[4]);
+ ushort c = (ushort)((ushort)hashCode[7] << 8 | (ushort)hashCode[6]);
+ byte d = hashCode[8];
+ byte e = hashCode[9];
+ byte f = hashCode[10];
+ byte g = hashCode[11];
+ byte h = hashCode[12];
+ byte i = hashCode[13];
+ byte j = hashCode[14];
+ byte k = hashCode[15];
// modify the guid data so it decodes to the form of a "random" guid ala rfc4122
- guidPtr[7] = (byte)((guidPtr[7] & 0x0f) | (4 << 4));
- guidPtr[8] = (byte)((guidPtr[8] & 0x3f) | (2 << 6));
+ c = (ushort)((c & 0x0fff) | (4 << 12));
+ d = (byte)((d & 0x3f) | (2 << 6));
+ Guid guid = new Guid((int)a, (short)b, (short)c, d, e, f, g, h, i, j, k);
// compute a random-looking stamp from the remaining bits, but with the upper bit set
uint stamp = 0x80000000u | ((uint)hashCode[19] << 24 | (uint)hashCode[18] << 16 | (uint)hashCode[17] << 8 | hashCode[16]);