From b144f717560b173d3a26c03cccc89443d6cc42f3 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Thu, 22 Oct 2020 22:06:59 +0200 Subject: [PATCH] Fixed MemoryStream seek to end validation --- .../Streams/MemoryStream.Validate.cs | 4 +-- .../Streams/Test_MemoryStream.cs | 36 +++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/Microsoft.Toolkit.HighPerformance/Streams/MemoryStream.Validate.cs b/Microsoft.Toolkit.HighPerformance/Streams/MemoryStream.Validate.cs index 9cd0ff62936..2f35380918f 100644 --- a/Microsoft.Toolkit.HighPerformance/Streams/MemoryStream.Validate.cs +++ b/Microsoft.Toolkit.HighPerformance/Streams/MemoryStream.Validate.cs @@ -13,14 +13,14 @@ namespace Microsoft.Toolkit.HighPerformance.Streams internal static partial class MemoryStream { /// - /// Validates the argument. + /// Validates the argument (it needs to be in the [0, length]) range. /// /// The new value being set. /// The maximum length of the target . [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void ValidatePosition(long position, int length) { - if ((ulong)position >= (ulong)length) + if ((ulong)position > (ulong)length) { ThrowArgumentOutOfRangeExceptionForPosition(); } diff --git a/UnitTests/UnitTests.HighPerformance.Shared/Streams/Test_MemoryStream.cs b/UnitTests/UnitTests.HighPerformance.Shared/Streams/Test_MemoryStream.cs index 8a9e19111cb..f2c63182c63 100644 --- a/UnitTests/UnitTests.HighPerformance.Shared/Streams/Test_MemoryStream.cs +++ b/UnitTests/UnitTests.HighPerformance.Shared/Streams/Test_MemoryStream.cs @@ -78,6 +78,42 @@ public void Test_MemoryStream_Seek() Assert.AreEqual(stream.Position, 32); } + // See https://github.com/windows-toolkit/WindowsCommunityToolkit/issues/3536 + [TestCategory("MemoryStream")] + [TestMethod] + public void Test_MemoryStream_WriteToEndAndRefreshPosition() + { + byte[] + array = new byte[10], + temp = new byte[1]; + ReadOnlyMemory memory = array; + + using var stream = memory.AsStream(); + + for (int i = 0; i < array.Length; i++) + { + int read = stream.Read(temp, 0, 1); + + Assert.AreEqual(read, 1); + Assert.AreEqual(stream.Position, i + 1); + } + + Assert.AreEqual(stream.Position, array.Length); + + // These should not throw, seeking to the end is valid + stream.Position = stream.Position; + Assert.AreEqual(stream.Position, array.Length); + + stream.Seek(array.Length, SeekOrigin.Begin); + Assert.AreEqual(stream.Position, array.Length); + + stream.Seek(0, SeekOrigin.Current); + Assert.AreEqual(stream.Position, array.Length); + + stream.Seek(0, SeekOrigin.End); + Assert.AreEqual(stream.Position, array.Length); + } + [TestCategory("MemoryStream")] [TestMethod] public void Test_MemoryStream_ReadWrite_Array()