Skip to content

Commit 861164c

Browse files
Fix NRE with UnicodeEncoding when target is an empty span (#97950)
* Fix NRE with UnicodeEncoding when target is an empty span * Faster check * Same fix for UTF32Encoding * Move test to NegativeEncodingTests * Apply same fixes in System.Text.Encoding.Codepages --------- Co-authored-by: Stephen Toub <stoub@microsoft.com>
1 parent 40ac297 commit 861164c

File tree

5 files changed

+10
-7
lines changed

5 files changed

+10
-7
lines changed

src/libraries/System.Private.CoreLib/src/System/Text/Encoding.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1297,7 +1297,7 @@ internal unsafe bool AddChar(char ch, int numBytes)
12971297
{
12981298
// Throw maybe
12991299
_bytes -= numBytes; // Didn't encode these bytes
1300-
_enc.ThrowCharsOverflow(_decoder, _bytes <= _byteStart); // Throw?
1300+
_enc.ThrowCharsOverflow(_decoder, _chars == _charStart); // Throw?
13011301
return false; // No throw, but no store either
13021302
}
13031303

@@ -1316,7 +1316,7 @@ internal unsafe bool AddChar(char ch1, char ch2, int numBytes)
13161316
{
13171317
// Throw maybe
13181318
_bytes -= numBytes; // Didn't encode these bytes
1319-
_enc.ThrowCharsOverflow(_decoder, _bytes <= _byteStart); // Throw?
1319+
_enc.ThrowCharsOverflow(_decoder, _chars == _charStart); // Throw?
13201320
return false; // No throw, but no store either
13211321
}
13221322
return AddChar(ch1, numBytes) && AddChar(ch2, numBytes);

src/libraries/System.Private.CoreLib/src/System/Text/UTF32Encoding.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -934,7 +934,7 @@ internal override unsafe int GetChars(byte* bytes, int byteCount,
934934
if (iChar >= 0x10000)
935935
{
936936
// Surrogates take 2
937-
if (chars >= charEnd - 1)
937+
if (charEnd - chars < 2)
938938
{
939939
// Throwing or stopping
940940
// We either read enough bytes for bytes-=4 to work, or we're

src/libraries/System.Private.CoreLib/src/System/Text/UnicodeEncoding.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1535,7 +1535,7 @@ internal sealed override unsafe int GetChars(
15351535
}
15361536

15371537
// Valid surrogate pair, add our lastChar (will need 2 chars)
1538-
if (chars >= charEnd - 1)
1538+
if (charEnd - chars < 2)
15391539
{
15401540
// couldn't find room for this surrogate pair
15411541
// We either advanced bytes or chars should == charStart and throw below

src/libraries/System.Runtime/tests/System.Text.Encoding.Tests/NegativeEncodingTests.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -623,6 +623,9 @@ void VerifyOutParams()
623623
// Chars does not have enough space
624624
AssertExtensions.Throws<ArgumentException>("chars", () => decoder.Convert(new byte[4], 0, 4, new char[0], 0, 0, flush, out charsUsed, out bytesUsed, out completed));
625625
VerifyOutParams();
626+
627+
AssertExtensions.Throws<ArgumentException>("chars", () => decoder.Convert(encoding.GetBytes("\uD800\uDC00".ToCharArray()).AsSpan(), new char[0].AsSpan(), flush, out charsUsed, out bytesUsed, out completed));
628+
VerifyOutParams();
626629
}
627630

628631
[Theory]

src/libraries/System.Text.Encoding.CodePages/src/System/Text/EncodingCharBuffer.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ internal unsafe bool AddChar(char ch, int numBytes)
5353
{
5454
// Throw maybe
5555
_bytes -= numBytes; // Didn't encode these bytes
56-
_enc.ThrowCharsOverflow(_decoder, _bytes <= _byteStart); // Throw?
56+
_enc.ThrowCharsOverflow(_decoder, _chars == _charStart); // Throw?
5757
return false; // No throw, but no store either
5858
}
5959

@@ -72,11 +72,11 @@ internal unsafe bool AddChar(char ch)
7272
internal unsafe bool AddChar(char ch1, char ch2, int numBytes)
7373
{
7474
// Need room for 2 chars
75-
if (_chars >= _charEnd - 1)
75+
if (_charEnd - _chars < 2)
7676
{
7777
// Throw maybe
7878
_bytes -= numBytes; // Didn't encode these bytes
79-
_enc.ThrowCharsOverflow(_decoder, _bytes <= _byteStart); // Throw?
79+
_enc.ThrowCharsOverflow(_decoder, _chars == _charStart); // Throw?
8080
return false; // No throw, but no store either
8181
}
8282
return AddChar(ch1, numBytes) && AddChar(ch2, numBytes);

0 commit comments

Comments
 (0)