Windowscommunitytoolkit: MemoryStream.ValidatePosition throws when Position == length

Created on 20 Oct 2020  路  6Comments  路  Source: windows-toolkit/WindowsCommunityToolkit

If you read to the end of the MemoryStream, Position == length. If you then try to
call mstrm.Postion = mstrm.Position, it throws an ArgOutOfRangeException

var foo = new byte[10];
var rom = new ReadOnlyMemory<byte>(foo);
using (var stream = rom.AsStream())
{
    for (int i = 0; i < foof.Length; i++)
    {
        var b = new byte[1];
        stream.Read(b, 0, 1);
        Console.WriteLine(stream.Position);
     }
    //Throws out of range exception
     stream.Position = stream.Position;
}

In MemoryStream.cs, should probably be '>' rather than '>=' to be consistent with the behavior of other streams

public static void ValidatePosition(long position, int length)
{
    if ((ulong)position >= (ulong)length)
    {
        ThrowArgumentOutOfRangeExceptionForPosition();
    }
}

NuGet Package(s): microsoft.toolkit.highperformance

Package Version(s): v6.1.1

Windows 10 Build Number:

  • [ ] Fall Creators Update (16299)
  • [ ] April 2018 Update (17134)
  • [x] October 2018 Update (17763)
  • [ ] May 2019 Update (18362)
  • [ ] May 2020 Update (19041)
  • [ ] Insider Build (build number: )

App min and target version:

  • [ ] Fall Creators Update (16299)
  • [ ] April 2018 Update (17134)
  • [x] October 2018 Update (17763)
  • [ ] May 2019 Update (18362)
  • [ ] May 2020 Update (19041)
  • [ ] Insider Build (xxxxx)

Device form factor:

  • [x] Desktop
  • [ ] Xbox
  • [ ] Surface Hub
  • [ ] IoT

Visual Studio

  • [ ] 2017 (version: )
  • [x] 2019 (version: )
  • [ ] 2019 Preview (version: )
Completed bug high-performance 馃殏

All 6 comments

Hello tombarry25, thank you for opening an issue with us!

I have automatically added a "needs triage" label to help get things started. Our team will analyze and investigate the issue, and escalate it to the relevant team if possible. Other community members may also look into the issue and provide feedback 馃檶

@tombarry25 Can you please provide detailed information and expected behavior? Screenshots/gifs are highly recommended. Thanks!

Hello Kyaa,

Not sure what else I can provide. The issue I entered has code to reproduce the error and even where I think the problem might be.

So, unlike other streams, you are unable to set the Position of the Microsoft.Toolkit.HighPerformance.Streams.MemoryStream equal to its Length. You also are unable to seek to the end of the stream either. Both throw an out of range exception.

The snippet of code I provided demonstrates reading to the end of the stream so that stream.Position == stream.Length. But if you then try to set the stream鈥檚 position to the value it already has it throws. I believe it throws because the ValidatePosition(long position, int length) compares position to length with a >= when it should be strictly >. In other words, setting Postion equal to Length for a stream should not throw.

Hope this helps.

@Sergio0694 this one's for you! 馃檪

Hey @tombarry25, thanks for the detailed issue and repro, and for spotting the bug! 馃槃

You were absolutely correct, the stream shouldn't throw an exception when seeking to the end.
Added a fix and a new unit test including the repro you provided, along with further validation for other seeking APIs.

Sounds good. Thanks for the quick turnaround.

Was this page helpful?
0 / 5 - 0 ratings