-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Description
I'm using .NET core 5.0, F#. Wanted to access standard input via Stream abstraction. However, quickly ran into bugs.
Minimal sample program:
let main argv =
use stdin = System.Console.OpenStandardInput()
printfn "Enter some text."
printfn "First byte: %d" (stdin.ReadByte())
This doesn't work for larger inputs on the interactive command line. For example, it doesn't work for abcdefghijklmnop<ENTER>
. It reports a System.ArgumentException (debug stack below).
Note that it does work with one byte fewer, i.e. if we have just 16 bytes in the input abcdefghijklmno<ENTER>
will give the correct 97 value. It also works if piping standard input from another source, e.g. echo "abcdefghijklmnopqrstuvwxyz" | dotnet run
will give the correct 97 value. So the issue seems specific to the command line interactive input.
If I use System.Console.Read()
instead, I also receive the correct 97 value for larger inputs, though I get 8594 (0x2192) instead of a byte if my first character is Unicode right arrow →
. I actually wanted bytes as originally input for my use case, was hoping to avoid all the implicit conversions to chars then back to UTF-8.
Configuration
Using Linux (Ubuntu 20.04) x86
Dotnet version 5.0.403
Regression?
I haven't tried on other configurations.
Other information
$ dotnet run
Enter some text.
abcdefghijklmnop
Unhandled exception. System.ArgumentException: The output byte buffer is too small to contain the encoded data, encoding 'Unicode (UTF-8)' fallback 'System.Text.EncoderReplacementFallback'. (Parameter 'bytes')
at System.Text.Encoding.ThrowBytesOverflow()
at System.Text.Encoding.ThrowBytesOverflow(EncoderNLS encoder, Boolean nothingEncoded)
at System.Text.Encoding.GetBytesWithFallback(ReadOnlySpan`1 chars, Int32 originalCharsLength, Span`1 bytes, Int32 originalBytesLength, EncoderNLS encoder)
at System.Text.Encoding.GetBytesWithFallback(Char* pOriginalChars, Int32 originalCharCount, Byte* pOriginalBytes, Int32 originalByteCount, Int32 charsConsumedSoFar, Int32 bytesWrittenSoFar, EncoderNLS encoder)
at System.Text.Encoding.GetBytes(Char* pChars, Int32 charCount, Byte* pBytes, Int32 byteCount, EncoderNLS encoder)
at System.Text.EncoderNLS.Convert(Char* chars, Int32 charCount, Byte* bytes, Int32 byteCount, Boolean flush, Int32& charsUsed, Int32& bytesUsed, Boolean& completed)
at System.Text.Encoder.Convert(ReadOnlySpan`1 chars, Span`1 bytes, Boolean flush, Int32& charsUsed, Int32& bytesUsed, Boolean& completed)
at System.IO.StdInReader.ReadLine(Byte[] buffer, Int32 offset, Int32 count)
at System.ConsolePal.UnixConsoleStream.Read(Byte[] buffer, Int32 offset, Int32 count)
at System.IO.Stream.ReadByte()
at Program.main(String[] argv) in /home/dmbarbour/projects/tst/Program.fs:line 9