From 651daa301c3098c70dba55ac0c4d3c50c506b658 Mon Sep 17 00:00:00 2001 From: xtqqczze <45661989+xtqqczze@users.noreply.github.com> Date: Sat, 5 Oct 2024 17:10:55 +0100 Subject: [PATCH 1/2] Avoid `OverflowException` in `Boolean.TryFormat` `MemoryMarshal.AsBytes` would throw unnecessarily when `destination.Length` exceeds 0x3FFFFFFF. --- .../System.Private.CoreLib/src/System/Boolean.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Boolean.cs b/src/libraries/System.Private.CoreLib/src/System/Boolean.cs index 07db907c2b1ed3..f8773d47ecf046 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Boolean.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Boolean.cs @@ -96,20 +96,20 @@ public bool TryFormat(Span destination, out int charsWritten) { if (m_value) { - if (destination.Length > 3) + if (destination.Length >= 4) { ulong true_val = BitConverter.IsLittleEndian ? 0x65007500720054ul : 0x54007200750065ul; // "True" - MemoryMarshal.Write(MemoryMarshal.AsBytes(destination), in true_val); + Unsafe.WriteUnaligned(ref Unsafe.As(ref MemoryMarshal.GetReference(destination)), true_val); charsWritten = 4; return true; } } else { - if (destination.Length > 4) + if (destination.Length >= 5) { ulong fals_val = BitConverter.IsLittleEndian ? 0x73006C00610046ul : 0x460061006C0073ul; // "Fals" - MemoryMarshal.Write(MemoryMarshal.AsBytes(destination), in fals_val); + Unsafe.WriteUnaligned(ref Unsafe.As(ref MemoryMarshal.GetReference(destination)), fals_val); destination[4] = 'e'; charsWritten = 5; return true; From 917c458c306ab3ef076087959ea951c58c7d3549 Mon Sep 17 00:00:00 2001 From: xtqqczze <45661989+xtqqczze@users.noreply.github.com> Date: Sun, 6 Oct 2024 20:22:06 +0100 Subject: [PATCH 2/2] Use `string.TryCopyTo` See https://github.com/dotnet/runtime/pull/108575 --- .../System.Private.CoreLib/src/System/Boolean.cs | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Boolean.cs b/src/libraries/System.Private.CoreLib/src/System/Boolean.cs index f8773d47ecf046..6869de20000279 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Boolean.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Boolean.cs @@ -96,22 +96,17 @@ public bool TryFormat(Span destination, out int charsWritten) { if (m_value) { - if (destination.Length >= 4) + if (TrueLiteral.TryCopyTo(destination)) { - ulong true_val = BitConverter.IsLittleEndian ? 0x65007500720054ul : 0x54007200750065ul; // "True" - Unsafe.WriteUnaligned(ref Unsafe.As(ref MemoryMarshal.GetReference(destination)), true_val); - charsWritten = 4; + charsWritten = TrueLiteral.Length; return true; } } else { - if (destination.Length >= 5) + if (FalseLiteral.TryCopyTo(destination)) { - ulong fals_val = BitConverter.IsLittleEndian ? 0x73006C00610046ul : 0x460061006C0073ul; // "Fals" - Unsafe.WriteUnaligned(ref Unsafe.As(ref MemoryMarshal.GetReference(destination)), fals_val); - destination[4] = 'e'; - charsWritten = 5; + charsWritten = FalseLiteral.Length; return true; } }