summaryrefslogtreecommitdiff
path: root/src/System.Private.CoreLib
diff options
context:
space:
mode:
authorJan Kotas <jkotas@microsoft.com>2019-08-26 08:04:09 -0700
committerGitHub <noreply@github.com>2019-08-26 08:04:09 -0700
commit654cd7e0d39c16fe3adec6f67a27eb3b1304c35d (patch)
tree8a52c9e551044c8ce053cd538d1c703eb4851632 /src/System.Private.CoreLib
parent795458a84583d81a9f9e6952fc47fcfc9e58e73c (diff)
downloadcoreclr-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')
-rw-r--r--src/System.Private.CoreLib/shared/System/IO/BinaryReader.cs22
-rw-r--r--src/System.Private.CoreLib/shared/System/Text/DecoderNLS.cs2
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;
}
}