StreamReader .Peek broken?

Has anyone else observed that StreamReader.Peek() and .Read() seem to have a broken interaction with each other? In writing a parser, I noticed that if I use .Peek() to test a character and then .Read() to ‘eat’ that character if it is in the desired character set, the .Read will skip ahead one character in the stream if the .Peek() occured at an internal buffer boundary. For example, this code will drop one character if the token read occurs at a 512-byte boundary in the source stream:

StringBuilder sbToken = new StringBuilder();
do
{
    sbToken.Append(ch);
    if (IsValidTokenChar((char)sourceReader.Peek()))
        ch = (char)sourceReader.Read();
    else
        break;
} while (true);

The StreamReader above is reading across a memory stream that was derived from a string. The buffer appears to contain the right data given the contents of the original string.

I’m parsing Gcode using Peek() and Read() but so far didn’t notice any issues.

It might only occur when the underlying BaseStream is a MemoryStream. I have it on my list for this week to narrow it down and file an issue with Microsoft (and a pull request if the bug is obvious enough).

I know that ReadLine sometimes Peeks to the next Byte which might not in the buffer already.