summaryrefslogtreecommitdiff
path: root/src/System.Private.CoreLib
diff options
context:
space:
mode:
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;
}
}