Skip to content

Stream.Read<T>() makes incorrect assumptions about Stream.Read(Span)'s return value #513

@MihaZupan

Description

@MihaZupan

Describe the bug

The public static unsafe T Read<T>(this Stream stream) extension method makes the assumption that the Read(Span<byte>) must read exactly length bytes.
If it returns less than that, it throws with the message that the stream did not contain enough data.

T result = default;
int length = sizeof(T);
unsafe
{
if (stream.Read(new Span<byte>(&result, length)) != length)
{
ThrowInvalidOperationExceptionForEndOfStream();
}
}

The only time this assumption is correct is when the stream is a MemoryStream.
All other Stream implementations are free to return fewer bytes than requested and commonly do so.

Steps to reproduce

Have a stream like

class CustomStream : Stream
{
    private ReadOnlyMemory<byte> _bufferedBytes;

    public int Read(Span<byte> buffer)
    {
        if (!_bufferedBytes.IsEmpty)
        {
            int toCopy = Math.Min(_bufferedBytes.Length, buffer.Length);
            _bufferedBytes.Span.Slice(0, toCopy).CopyTo(buffer);
            _bufferedBytes = _bufferedBytes.Slice(toCopy);
            return toCopy;
        }

        return GetMoreBytes(buffer);
    }
}

And call

stream.Read<int>();

You may hit an exception telling you that the stream ended even though more data is actually available, you just happened to read while the buffer had fewer than 4 bytes in it.

Expected behavior

The Read helper would loop until either receiving length bytes, or until the Read returned 0 indicating the end of the stream.

IDE and version

VS 2022 Preview

Nuget packages

  • CommunityToolkit.Common
  • CommunityToolkit.Diagnostics
  • CommunityToolkit.HighPerformance
  • CommunityToolkit.Mvvm (aka MVVM Toolkit)

Additional context

I'm not actually using this library, just saw the code as someone mentioned it in dotnet/runtime.

Help us help you

No, just wanted to report this

Metadata

Metadata

Assignees

No one assigned

    Labels

    bug 🐛An unexpected issue that highlights incorrect behaviorhigh-performance 🚂Issues/PRs for the HighPerformance package

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions