Browse Source

Fix SlicedStream.Seek(offset, SeekOrigin.End) (#18313)

* Fix SlicedStream.Seek(offset, SeekOrigin.End)

This fixes https://github.com/AvaloniaUI/Avalonia/issues/13604

The offset _from is applied in set_Position, so applying it also in Seek mispositions the stream. ZipArchive exposes the problem by seeking to the end to read the table of contents.

* Add tests for SlicedStream

---------

Co-authored-by: Julien Lebosquain <[email protected]>
pjt33 8 months ago
parent
commit
11b5d421c4

+ 1 - 1
src/Avalonia.Base/Platform/Internal/SlicedStream.cs

@@ -29,7 +29,7 @@ internal class SlicedStream : Stream
         if (origin == SeekOrigin.Begin)
             Position = offset;
         if (origin == SeekOrigin.End)
-            Position = _from + Length + offset;
+            Position = Length + offset;
         if (origin == SeekOrigin.Current)
             Position = Position + offset;
         return Position;

+ 29 - 0
tests/Avalonia.Base.UnitTests/Platform/SlicedStreamTests.cs

@@ -0,0 +1,29 @@
+using System.IO;
+using Avalonia.Platform.Internal;
+using Xunit;
+
+namespace Avalonia.Base.UnitTests;
+
+public class SlicedStreamTests
+{
+    [Theory]
+    [InlineData(2, SeekOrigin.Begin, 22, 2, 9)]
+    [InlineData(2, SeekOrigin.Current, 22, 17, 24)]
+    [InlineData(-2, SeekOrigin.End, 22, 40, 47)]
+    public void Seek_Works(
+        long offset,
+        SeekOrigin origin,
+        long startingUnderlyingPosition,
+        long expectedPosition,
+        long expectedUnderlyingPosition)
+    {
+        var memoryStream = new MemoryStream(new byte[1024]);
+        var slicedStream = new SlicedStream(memoryStream, 7, 42);
+        memoryStream.Position = startingUnderlyingPosition;
+
+        slicedStream.Seek(offset, origin);
+
+        Assert.Equal(expectedPosition, slicedStream.Position);
+        Assert.Equal(expectedUnderlyingPosition, memoryStream.Position);
+    }
+}