Skip to content

Commit 69bb1a4

Browse files
Convert.FromHexString exception with too large buffer (#105426)
* Fix destination slicing * Correct destination slice * correct test expected value * Apply suggestions and add more unit tests. --------- Co-authored-by: Eirik Tsarpalis <[email protected]>
1 parent 58d6c58 commit 69bb1a4

File tree

2 files changed

+59
-5
lines changed

2 files changed

+59
-5
lines changed

src/libraries/System.Private.CoreLib/src/System/Convert.cs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2999,19 +2999,27 @@ public static OperationStatus FromHexString(ReadOnlySpan<char> source, Span<byte
29992999
return remainder == 1 ? OperationStatus.NeedMoreData : OperationStatus.Done;
30003000
}
30013001

3002-
var result = OperationStatus.Done;
3002+
OperationStatus result;
30033003

30043004
if (destination.Length < quotient)
30053005
{
30063006
source = source.Slice(0, destination.Length * 2);
30073007
quotient = destination.Length;
30083008
result = OperationStatus.DestinationTooSmall;
30093009
}
3010-
else if (remainder == 1)
3010+
else
30113011
{
3012-
source = source.Slice(0, source.Length - 1);
3013-
destination = destination.Slice(0, destination.Length - 1);
3014-
result = OperationStatus.NeedMoreData;
3012+
if (remainder == 1)
3013+
{
3014+
source = source.Slice(0, source.Length - 1);
3015+
result = OperationStatus.NeedMoreData;
3016+
}
3017+
else
3018+
{
3019+
result = OperationStatus.Done;
3020+
}
3021+
3022+
destination = destination.Slice(0, quotient);
30153023
}
30163024

30173025
if (!HexConverter.TryDecodeFromUtf16(source, destination, out charsConsumed))

src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/Convert.FromHexString.cs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,42 @@ public static void TooShortDestination()
136136
Assert.Equal(destinationSize, bytesWritten);
137137
}
138138

139+
[Fact]
140+
public static void TooLongDestination()
141+
{
142+
string hex = Convert.ToHexString([255, 255, 255]);
143+
byte[] buffer = new byte[100];
144+
var status = Convert.FromHexString(hex, buffer, out int charsConsumed, out int bytesWritten);
145+
146+
Assert.Equal(OperationStatus.Done, status);
147+
Assert.Equal(hex.Length, charsConsumed);
148+
Assert.Equal(hex.Length / 2, bytesWritten);
149+
}
150+
151+
[Fact]
152+
public static void ExactDestination()
153+
{
154+
string hex = "ffffff";
155+
byte[] buffer = new byte[3];
156+
var status = Convert.FromHexString(hex, buffer, out int charsConsumed, out int bytesWritten);
157+
158+
Assert.Equal(OperationStatus.Done, status);
159+
Assert.Equal(hex.Length, charsConsumed);
160+
Assert.Equal(hex.Length / 2, bytesWritten);
161+
}
162+
163+
[Fact]
164+
public static void ExactDestination_TrailingCharacter()
165+
{
166+
string hex = "fffff";
167+
byte[] buffer = new byte[2];
168+
var status = Convert.FromHexString(hex, buffer, out int charsConsumed, out int bytesWritten);
169+
170+
Assert.Equal(OperationStatus.NeedMoreData, status);
171+
Assert.Equal(hex.Length - 1, charsConsumed);
172+
Assert.Equal(hex.Length / 2, bytesWritten);
173+
}
174+
139175
[Fact]
140176
public static void NeedMoreData_OrFormatException()
141177
{
@@ -152,6 +188,7 @@ public static void NeedMoreData_OrFormatException()
152188
Assert.Equal(0, consumed);
153189
Assert.Equal(0, written);
154190

191+
// Odd length
155192
spanHex = hex.AsSpan(0, hex.Length - 1);
156193

157194
var oneOffResult = Convert.FromHexString(spanHex, destination, out consumed, out written);
@@ -160,6 +197,15 @@ public static void NeedMoreData_OrFormatException()
160197
Assert.Equal(OperationStatus.NeedMoreData, oneOffResult);
161198
Assert.Equal(spanHex.Length - 1, consumed);
162199
Assert.Equal((spanHex.Length - 1) / 2, written);
200+
201+
// Even length
202+
spanHex = hex.AsSpan(0, hex.Length - 2);
203+
204+
var twoOffResult = Convert.FromHexString(spanHex, destination, out consumed, out written);
205+
206+
Assert.Equal(OperationStatus.Done, twoOffResult);
207+
Assert.Equal(spanHex.Length, consumed);
208+
Assert.Equal(spanHex.Length / 2, written);
163209
}
164210
}
165211
}

0 commit comments

Comments
 (0)