From 01675ac810a4f4f2f62e7d750b25afff132a1a31 Mon Sep 17 00:00:00 2001 From: xtqqczze <45661989+xtqqczze@users.noreply.github.com> Date: Thu, 11 Jul 2024 12:39:35 +0100 Subject: [PATCH 1/3] Do not ignore `MemoryMarshal.TryWrite` result in `Guid` --- .../System.Private.CoreLib/src/System/Guid.cs | 34 ++++++++++++------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Guid.cs b/src/libraries/System.Private.CoreLib/src/System/Guid.cs index 4d3419236ec5f8..79e259beac7fd9 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Guid.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Guid.cs @@ -909,54 +909,61 @@ private static bool IsHexPrefix(ReadOnlySpan str, int i) => // Returns an unsigned byte array containing the GUID. public byte[] ToByteArray() { - var g = new byte[16]; + byte[] array = new byte[16]; + if (BitConverter.IsLittleEndian) { - MemoryMarshal.TryWrite(g, in this); + Unsafe.WriteUnaligned(ref MemoryMarshal.GetArrayDataReference(array), this); } else { // slower path for BigEndian Guid guid = new Guid(MemoryMarshal.AsBytes(new ReadOnlySpan(in this)), false); - MemoryMarshal.TryWrite(g, in guid); + Unsafe.WriteUnaligned(ref MemoryMarshal.GetArrayDataReference(array), guid); } - return g; + + return array; } // Returns an unsigned byte array containing the GUID. public byte[] ToByteArray(bool bigEndian) { - var g = new byte[16]; + byte[] array = new byte[16]; + if (BitConverter.IsLittleEndian != bigEndian) { - MemoryMarshal.TryWrite(g, in this); + Unsafe.WriteUnaligned(ref MemoryMarshal.GetArrayDataReference(array), this); } else { // slower path for Reverse Guid guid = new Guid(MemoryMarshal.AsBytes(new ReadOnlySpan(in this)), bigEndian); - MemoryMarshal.TryWrite(g, in guid); + Unsafe.WriteUnaligned(ref MemoryMarshal.GetArrayDataReference(array), guid); } - return g; + + return array; } // Returns whether bytes are successfully written to given span. public bool TryWriteBytes(Span destination) { if (destination.Length < 16) + { return false; + } if (BitConverter.IsLittleEndian) { - MemoryMarshal.TryWrite(destination, in this); + Unsafe.WriteUnaligned(ref MemoryMarshal.GetReference(destination), this); } else { // slower path for BigEndian Guid guid = new Guid(MemoryMarshal.AsBytes(new ReadOnlySpan(in this)), false); - MemoryMarshal.TryWrite(destination, in guid); + Unsafe.WriteUnaligned(ref MemoryMarshal.GetReference(destination), guid); } + return true; } @@ -971,14 +978,15 @@ public bool TryWriteBytes(Span destination, bool bigEndian, out int bytesW if (BitConverter.IsLittleEndian != bigEndian) { - MemoryMarshal.TryWrite(destination, in this); + Unsafe.WriteUnaligned(ref MemoryMarshal.GetReference(destination), this); } else { // slower path for Reverse Guid guid = new Guid(MemoryMarshal.AsBytes(new ReadOnlySpan(in this)), bigEndian); - MemoryMarshal.TryWrite(destination, in guid); + Unsafe.WriteUnaligned(ref MemoryMarshal.GetReference(destination), guid); } + bytesWritten = 16; return true; } @@ -1085,7 +1093,7 @@ public int CompareTo(Guid value) if (value._k != _k) { return GetResult(_k, value._k); - } + } return 0; } From 811533c5c5289236511c947f5a8c189917834b56 Mon Sep 17 00:00:00 2001 From: xtqqczze <45661989+xtqqczze@users.noreply.github.com> Date: Tue, 23 Jul 2024 11:46:17 +0100 Subject: [PATCH 2/3] Revert "Do not ignore `MemoryMarshal.TryWrite` result in `Guid`" This reverts commit 01675ac810a4f4f2f62e7d750b25afff132a1a31. --- .../System.Private.CoreLib/src/System/Guid.cs | 34 +++++++------------ 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Guid.cs b/src/libraries/System.Private.CoreLib/src/System/Guid.cs index 79e259beac7fd9..4d3419236ec5f8 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Guid.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Guid.cs @@ -909,61 +909,54 @@ private static bool IsHexPrefix(ReadOnlySpan str, int i) => // Returns an unsigned byte array containing the GUID. public byte[] ToByteArray() { - byte[] array = new byte[16]; - + var g = new byte[16]; if (BitConverter.IsLittleEndian) { - Unsafe.WriteUnaligned(ref MemoryMarshal.GetArrayDataReference(array), this); + MemoryMarshal.TryWrite(g, in this); } else { // slower path for BigEndian Guid guid = new Guid(MemoryMarshal.AsBytes(new ReadOnlySpan(in this)), false); - Unsafe.WriteUnaligned(ref MemoryMarshal.GetArrayDataReference(array), guid); + MemoryMarshal.TryWrite(g, in guid); } - - return array; + return g; } // Returns an unsigned byte array containing the GUID. public byte[] ToByteArray(bool bigEndian) { - byte[] array = new byte[16]; - + var g = new byte[16]; if (BitConverter.IsLittleEndian != bigEndian) { - Unsafe.WriteUnaligned(ref MemoryMarshal.GetArrayDataReference(array), this); + MemoryMarshal.TryWrite(g, in this); } else { // slower path for Reverse Guid guid = new Guid(MemoryMarshal.AsBytes(new ReadOnlySpan(in this)), bigEndian); - Unsafe.WriteUnaligned(ref MemoryMarshal.GetArrayDataReference(array), guid); + MemoryMarshal.TryWrite(g, in guid); } - - return array; + return g; } // Returns whether bytes are successfully written to given span. public bool TryWriteBytes(Span destination) { if (destination.Length < 16) - { return false; - } if (BitConverter.IsLittleEndian) { - Unsafe.WriteUnaligned(ref MemoryMarshal.GetReference(destination), this); + MemoryMarshal.TryWrite(destination, in this); } else { // slower path for BigEndian Guid guid = new Guid(MemoryMarshal.AsBytes(new ReadOnlySpan(in this)), false); - Unsafe.WriteUnaligned(ref MemoryMarshal.GetReference(destination), guid); + MemoryMarshal.TryWrite(destination, in guid); } - return true; } @@ -978,15 +971,14 @@ public bool TryWriteBytes(Span destination, bool bigEndian, out int bytesW if (BitConverter.IsLittleEndian != bigEndian) { - Unsafe.WriteUnaligned(ref MemoryMarshal.GetReference(destination), this); + MemoryMarshal.TryWrite(destination, in this); } else { // slower path for Reverse Guid guid = new Guid(MemoryMarshal.AsBytes(new ReadOnlySpan(in this)), bigEndian); - Unsafe.WriteUnaligned(ref MemoryMarshal.GetReference(destination), guid); + MemoryMarshal.TryWrite(destination, in guid); } - bytesWritten = 16; return true; } @@ -1093,7 +1085,7 @@ public int CompareTo(Guid value) if (value._k != _k) { return GetResult(_k, value._k); - } + } return 0; } From c29f826751198a694d2021addb64c9603babcc21 Mon Sep 17 00:00:00 2001 From: xtqqczze <45661989+xtqqczze@users.noreply.github.com> Date: Tue, 23 Jul 2024 11:51:58 +0100 Subject: [PATCH 3/3] Minimal fix --- .../System.Private.CoreLib/src/System/Guid.cs | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Guid.cs b/src/libraries/System.Private.CoreLib/src/System/Guid.cs index 4d3419236ec5f8..e49662339aa97a 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Guid.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Guid.cs @@ -909,53 +909,53 @@ private static bool IsHexPrefix(ReadOnlySpan str, int i) => // Returns an unsigned byte array containing the GUID. public byte[] ToByteArray() { - var g = new byte[16]; + var bytes = new byte[16]; if (BitConverter.IsLittleEndian) { - MemoryMarshal.TryWrite(g, in this); + MemoryMarshal.Write(bytes, in this); } else { // slower path for BigEndian Guid guid = new Guid(MemoryMarshal.AsBytes(new ReadOnlySpan(in this)), false); - MemoryMarshal.TryWrite(g, in guid); + MemoryMarshal.Write(bytes, in guid); } - return g; + return bytes; } // Returns an unsigned byte array containing the GUID. public byte[] ToByteArray(bool bigEndian) { - var g = new byte[16]; + var bytes = new byte[16]; if (BitConverter.IsLittleEndian != bigEndian) { - MemoryMarshal.TryWrite(g, in this); + MemoryMarshal.Write(bytes, in this); } else { // slower path for Reverse Guid guid = new Guid(MemoryMarshal.AsBytes(new ReadOnlySpan(in this)), bigEndian); - MemoryMarshal.TryWrite(g, in guid); + MemoryMarshal.Write(bytes, in guid); } - return g; + return bytes; } // Returns whether bytes are successfully written to given span. public bool TryWriteBytes(Span destination) { - if (destination.Length < 16) + if ((uint)destination.Length < 16) return false; if (BitConverter.IsLittleEndian) { - MemoryMarshal.TryWrite(destination, in this); + MemoryMarshal.Write(destination, in this); } else { // slower path for BigEndian Guid guid = new Guid(MemoryMarshal.AsBytes(new ReadOnlySpan(in this)), false); - MemoryMarshal.TryWrite(destination, in guid); + MemoryMarshal.Write(destination, in guid); } return true; } @@ -963,7 +963,7 @@ public bool TryWriteBytes(Span destination) // Returns whether bytes are successfully written to given span. public bool TryWriteBytes(Span destination, bool bigEndian, out int bytesWritten) { - if (destination.Length < 16) + if ((uint)destination.Length < 16) { bytesWritten = 0; return false; @@ -971,13 +971,13 @@ public bool TryWriteBytes(Span destination, bool bigEndian, out int bytesW if (BitConverter.IsLittleEndian != bigEndian) { - MemoryMarshal.TryWrite(destination, in this); + MemoryMarshal.Write(destination, in this); } else { // slower path for Reverse Guid guid = new Guid(MemoryMarshal.AsBytes(new ReadOnlySpan(in this)), bigEndian); - MemoryMarshal.TryWrite(destination, in guid); + MemoryMarshal.Write(destination, in guid); } bytesWritten = 16; return true;