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

Commit 4e29494

Browse files
[release/3.1] Port fix to revert EncoderNLS and DecoderNLS Convert changes (#27996)
1 parent f14483f commit 4e29494

File tree

3 files changed

+38
-10
lines changed

3 files changed

+38
-10
lines changed

src/System.Private.CoreLib/shared/System/Text/DecoderNLS.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -207,12 +207,10 @@ public unsafe override void Convert(byte* bytes, int byteCount,
207207
charsUsed = _encoding.GetChars(bytes, byteCount, chars, charCount, this);
208208
bytesUsed = _bytesUsed;
209209

210-
// Per MSDN, "The completed output parameter indicates whether all the data in the input
211-
// buffer was converted and stored in the output buffer." That means we've successfully
212-
// consumed all the input _and_ there's no pending state or fallback data remaining to be output.
210+
// See comment in EncoderNLS.Convert for the details of the logic below.
213211

214212
completed = (bytesUsed == byteCount)
215-
&& !this.HasState
213+
&& (!flush || !this.HasState)
216214
&& (_fallbackBuffer is null || _fallbackBuffer.Remaining == 0);
217215

218216
// Our data thingy are now full, we can return

src/System.Private.CoreLib/shared/System/Text/EncoderNLS.cs

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -194,12 +194,39 @@ public override unsafe void Convert(char* chars, int charCount,
194194
bytesUsed = _encoding.GetBytes(chars, charCount, bytes, byteCount, this);
195195
charsUsed = _charsUsed;
196196

197-
// Per MSDN, "The completed output parameter indicates whether all the data in the input
198-
// buffer was converted and stored in the output buffer." That means we've successfully
199-
// consumed all the input _and_ there's no pending state or fallback data remaining to be output.
197+
// If the 'completed' out parameter is set to false, it means one of two things:
198+
// a) this call to Convert did not consume the entire source buffer; or
199+
// b) this call to Convert did consume the entire source buffer, but there's
200+
// still pending data that needs to be written to the destination buffer.
201+
//
202+
// In either case, the caller should slice the input buffer, provide a fresh
203+
// destination buffer, and call Convert again in a loop until 'completed' is true.
204+
//
205+
// The caller *must* specify flush = true on the final iteration(s) of the loop
206+
// and iterate until 'completed' is set to true. Otherwise data loss may occur.
207+
//
208+
// Technically, the expected logic is detailed below.
209+
//
210+
// If 'flush' = false, the 'completed' parameter MUST be set to false if not all
211+
// elements of the source buffer have been consumed. The 'completed' parameter MUST
212+
// be set to true once the entire source buffer has been consumed and there is no
213+
// pending data for the destination buffer. (In other words, the 'completed' parameter
214+
// MUST be set to true if passing a zero-length source buffer and an infinite-length
215+
// destination buffer will make no forward progress.) The 'completed' parameter value
216+
// is undefined for the case where all source data has been consumed but there remains
217+
// pending data for the destination buffer.
218+
//
219+
// If 'flush' = true, the 'completed' parameter is set to true IF AND ONLY IF:
220+
// a) all elements of the source buffer have been transcoded into the destination buffer; AND
221+
// b) there remains no internal partial read state within this instance; AND
222+
// c) there remains no pending data for the destination buffer.
223+
//
224+
// In other words, if 'flush' = true, then when 'completed' is set to true it should mean
225+
// that all data has been converted and that this instance is indistinguishable from a
226+
// freshly-reset instance.
200227

201228
completed = (charsUsed == charCount)
202-
&& !this.HasState
229+
&& (!flush || !this.HasState)
203230
&& (_fallbackBuffer is null || _fallbackBuffer.Remaining == 0);
204231

205232
// Our data thingys are now full, we can return

tests/CoreFX/CoreFX.issues.rsp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,12 @@
7070
# https://github.com/dotnet/coreclr/issues/22414
7171
-nomethod System.Numerics.Tests.ToStringTest.RunRegionSpecificStandardFormatToStringTests
7272

73-
# Failure in System.Text.Encoding.Tests due to bug fix in DecoderNLS.Convert
74-
# https://github.com/dotnet/coreclr/issues/27191
73+
# Failure in System.Text.Encoding.Tests due to bug fix in EncoderNLS.Convert and DecoderNLS.Convert
74+
# https://github.com/dotnet/coreclr/pull/27996
7575
-nomethod System.Text.Tests.DecoderConvert2.PosTest6
76+
-nomethod System.Text.Tests.DecoderConvert2.PosTest11
77+
-nomethod System.Text.Tests.EncoderConvert2.EncoderUTF8ConvertMixedASCIIUnicodeCharArrayPartial
78+
-nomethod System.Text.Tests.EncoderConvert2.EncoderUTF8ConvertUnicodeCharArrayPartial
7679

7780
# Timeout in System.Text.RegularExpressions.Tests.RegexMatchTests.Match_ExcessPrefix
7881
# https://github.com/dotnet/coreclr/issues/18912

0 commit comments

Comments
 (0)