diff options
author | Jan Kotas <jkotas@microsoft.com> | 2019-08-26 08:04:09 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-08-26 08:04:09 -0700 |
commit | 654cd7e0d39c16fe3adec6f67a27eb3b1304c35d (patch) | |
tree | 8a52c9e551044c8ce053cd538d1c703eb4851632 /src/System.Private.CoreLib/shared/System | |
parent | 795458a84583d81a9f9e6952fc47fcfc9e58e73c (diff) | |
download | coreclr-654cd7e0d39c16fe3adec6f67a27eb3b1304c35d.tar.gz coreclr-654cd7e0d39c16fe3adec6f67a27eb3b1304c35d.tar.bz2 coreclr-654cd7e0d39c16fe3adec6f67a27eb3b1304c35d.zip |
[release/3.0] Fix BinaryReader.ReadChars for fragmented Streams (#26324) (#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
Diffstat (limited to 'src/System.Private.CoreLib/shared/System')
-rw-r--r-- | src/System.Private.CoreLib/shared/System/IO/BinaryReader.cs | 22 | ||||
-rw-r--r-- | src/System.Private.CoreLib/shared/System/Text/DecoderNLS.cs | 2 |
2 files changed, 23 insertions, 1 deletions
diff --git a/src/System.Private.CoreLib/shared/System/IO/BinaryReader.cs b/src/System.Private.CoreLib/shared/System/IO/BinaryReader.cs index 560c998a44..037088c49b 100644 --- a/src/System.Private.CoreLib/shared/System/IO/BinaryReader.cs +++ b/src/System.Private.CoreLib/shared/System/IO/BinaryReader.cs @@ -390,6 +390,28 @@ namespace System.IO { 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; diff --git a/src/System.Private.CoreLib/shared/System/Text/DecoderNLS.cs b/src/System.Private.CoreLib/shared/System/Text/DecoderNLS.cs index 184d59d868..8cb3fffe1b 100644 --- a/src/System.Private.CoreLib/shared/System/Text/DecoderNLS.cs +++ b/src/System.Private.CoreLib/shared/System/Text/DecoderNLS.cs @@ -227,7 +227,7 @@ namespace System.Text { get { - return false; + return _leftoverByteCount != 0; } } |