Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

Commit

Permalink
[release/3.0] Fix BinaryReader.ReadChars for fragmented Streams (#26324
Browse files Browse the repository at this point in the history
…) (#26356)

BinaryReader.ReadChars incorrectly read more than necessary from the underlying Stream when multi-byte characters straddled the read chunks.

Fixes https://github.com/dotnet/corefx/issues/40455
  • Loading branch information
jkotas authored Aug 26, 2019
1 parent 795458a commit 654cd7e
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 1 deletion.
22 changes: 22 additions & 0 deletions src/System.Private.CoreLib/shared/System/IO/BinaryReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,28 @@ private int InternalReadChars(Span<char> buffer)
{
numBytes <<= 1;
}

// We do not want to read even a single byte more than necessary.
//
// Subtract pending bytes that the decoder may be holding onto. This assumes that each
// decoded char corresponds to one or more bytes. Note that custom encodings or encodings with
// a custom replacement sequence may violate this assumption.
if (numBytes > 1)
{
DecoderNLS? decoder = _decoder as DecoderNLS;
// For internal decoders, we can check whether the decoder has any pending state.
// For custom decoders, assume that the decoder has pending state.
if (decoder == null || decoder.HasState)
{
numBytes -= 1;

// The worst case is charsRemaining = 2 and UTF32Decoder holding onto 3 pending bytes. We need to read just
// one byte in this case.
if (_2BytesPerChar && numBytes > 2)
numBytes -= 2;
}
}

if (numBytes > MaxCharBytesSize)
{
numBytes = MaxCharBytesSize;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ internal virtual bool HasState
{
get
{
return false;
return _leftoverByteCount != 0;
}
}

Expand Down

0 comments on commit 654cd7e

Please sign in to comment.