From 0e2260d8e3436de82ea7890835cd59c411903035 Mon Sep 17 00:00:00 2001 From: hrrrrustic Date: Wed, 24 Jul 2024 23:55:52 +0300 Subject: [PATCH 1/4] Fix destination slicing --- .../src/System/Convert.cs | 10 ++++++--- .../System/Convert.FromHexString.cs | 22 +++++++++++++++++++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Convert.cs b/src/libraries/System.Private.CoreLib/src/System/Convert.cs index cee646eeb9fe6..5f764f18e89a2 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Convert.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Convert.cs @@ -3007,11 +3007,15 @@ public static OperationStatus FromHexString(ReadOnlySpan source, Span quotient) { - source = source.Slice(0, source.Length - 1); - destination = destination.Slice(0, destination.Length - 1); + if (remainder == 1) + { + source = source.Slice(0, source.Length - 1); + } + result = OperationStatus.NeedMoreData; + destination = destination.Slice(0, source.Length * 2); } if (!HexConverter.TryDecodeFromUtf16(source, destination, out charsConsumed)) diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/Convert.FromHexString.cs b/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/Convert.FromHexString.cs index dc80b4c0e9b78..8be5e0c082e42 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/Convert.FromHexString.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/Convert.FromHexString.cs @@ -136,6 +136,18 @@ public static void TooShortDestination() Assert.Equal(destinationSize, bytesWritten); } + [Fact] + public static void TooLongDestination() + { + string hex = Convert.ToHexString([255, 255, 255]); + byte[] buffer = new byte[100]; + var status = Convert.FromHexString(hex, buffer, out int charsConsumed, out int bytesWritten); + + Assert.Equal(OperationStatus.NeedMoreData, status); + Assert.Equal(hex.Length, charsConsumed); + Assert.Equal(hex.Length / 2, bytesWritten); + } + [Fact] public static void NeedMoreData_OrFormatException() { @@ -152,6 +164,7 @@ public static void NeedMoreData_OrFormatException() Assert.Equal(0, consumed); Assert.Equal(0, written); + // Odd length spanHex = hex.AsSpan(0, hex.Length - 1); var oneOffResult = Convert.FromHexString(spanHex, destination, out consumed, out written); @@ -160,6 +173,15 @@ public static void NeedMoreData_OrFormatException() Assert.Equal(OperationStatus.NeedMoreData, oneOffResult); Assert.Equal(spanHex.Length - 1, consumed); Assert.Equal((spanHex.Length - 1) / 2, written); + + // Even length + spanHex = hex.AsSpan(0, hex.Length - 2); + + var twoOffResult = Convert.FromHexString(spanHex, destination, out consumed, out written); + + Assert.Equal(OperationStatus.NeedMoreData, twoOffResult); + Assert.Equal(spanHex.Length - 1, consumed); + Assert.Equal((spanHex.Length - 1) / 2, written); } } } From f8668333f6d40eb9c92551225d8607421deb9b96 Mon Sep 17 00:00:00 2001 From: hrrrrustic Date: Thu, 25 Jul 2024 00:26:24 +0300 Subject: [PATCH 2/4] Correct destination slice --- src/libraries/System.Private.CoreLib/src/System/Convert.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Convert.cs b/src/libraries/System.Private.CoreLib/src/System/Convert.cs index 5f764f18e89a2..16c8f4e0bded8 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Convert.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Convert.cs @@ -3015,7 +3015,7 @@ public static OperationStatus FromHexString(ReadOnlySpan source, Span Date: Thu, 25 Jul 2024 09:47:08 +0300 Subject: [PATCH 3/4] correct test expected value --- .../System/Convert.FromHexString.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/Convert.FromHexString.cs b/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/Convert.FromHexString.cs index 8be5e0c082e42..faf73511e8994 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/Convert.FromHexString.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/Convert.FromHexString.cs @@ -180,8 +180,8 @@ public static void NeedMoreData_OrFormatException() var twoOffResult = Convert.FromHexString(spanHex, destination, out consumed, out written); Assert.Equal(OperationStatus.NeedMoreData, twoOffResult); - Assert.Equal(spanHex.Length - 1, consumed); - Assert.Equal((spanHex.Length - 1) / 2, written); + Assert.Equal(spanHex.Length, consumed); + Assert.Equal(spanHex.Length / 2, written); } } } From 88938e617b3feea1b4b66479596069e58cec8911 Mon Sep 17 00:00:00 2001 From: Eirik Tsarpalis Date: Mon, 12 Aug 2024 14:26:20 +0100 Subject: [PATCH 4/4] Apply suggestions and add more unit tests. --- .../src/System/Convert.cs | 10 +++++-- .../System/Convert.FromHexString.cs | 28 +++++++++++++++++-- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Convert.cs b/src/libraries/System.Private.CoreLib/src/System/Convert.cs index 24294be7cb498..8bf81152991ee 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Convert.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Convert.cs @@ -2999,7 +2999,7 @@ public static OperationStatus FromHexString(ReadOnlySpan source, Span source, Span quotient) + else { if (remainder == 1) { source = source.Slice(0, source.Length - 1); + result = OperationStatus.NeedMoreData; + } + else + { + result = OperationStatus.Done; } - result = OperationStatus.NeedMoreData; destination = destination.Slice(0, quotient); } diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/Convert.FromHexString.cs b/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/Convert.FromHexString.cs index faf73511e8994..fd8bcd6c8e05d 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/Convert.FromHexString.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/Convert.FromHexString.cs @@ -143,11 +143,35 @@ public static void TooLongDestination() byte[] buffer = new byte[100]; var status = Convert.FromHexString(hex, buffer, out int charsConsumed, out int bytesWritten); - Assert.Equal(OperationStatus.NeedMoreData, status); + Assert.Equal(OperationStatus.Done, status); + Assert.Equal(hex.Length, charsConsumed); + Assert.Equal(hex.Length / 2, bytesWritten); + } + + [Fact] + public static void ExactDestination() + { + string hex = "ffffff"; + byte[] buffer = new byte[3]; + var status = Convert.FromHexString(hex, buffer, out int charsConsumed, out int bytesWritten); + + Assert.Equal(OperationStatus.Done, status); Assert.Equal(hex.Length, charsConsumed); Assert.Equal(hex.Length / 2, bytesWritten); } + [Fact] + public static void ExactDestination_TrailingCharacter() + { + string hex = "fffff"; + byte[] buffer = new byte[2]; + var status = Convert.FromHexString(hex, buffer, out int charsConsumed, out int bytesWritten); + + Assert.Equal(OperationStatus.NeedMoreData, status); + Assert.Equal(hex.Length - 1, charsConsumed); + Assert.Equal(hex.Length / 2, bytesWritten); + } + [Fact] public static void NeedMoreData_OrFormatException() { @@ -179,7 +203,7 @@ public static void NeedMoreData_OrFormatException() var twoOffResult = Convert.FromHexString(spanHex, destination, out consumed, out written); - Assert.Equal(OperationStatus.NeedMoreData, twoOffResult); + Assert.Equal(OperationStatus.Done, twoOffResult); Assert.Equal(spanHex.Length, consumed); Assert.Equal(spanHex.Length / 2, written); }