diff --git a/src/SharpCompress/IO/IStreamStack.cs b/src/SharpCompress/IO/IStreamStack.cs index 56c020c8..943f7c25 100644 --- a/src/SharpCompress/IO/IStreamStack.cs +++ b/src/SharpCompress/IO/IStreamStack.cs @@ -143,7 +143,6 @@ namespace SharpCompress.IO var stack = new List(); Stream? current = stream as Stream; int lastBufferingIndex = -1; - int firstSeekableIndex = -1; Stream? firstSeekableStream = null; // Traverse the stack, collecting info @@ -161,7 +160,6 @@ namespace SharpCompress.IO // Find the first seekable stream (closest to the root) if (current != null && current.CanSeek) { - firstSeekableIndex = stack.Count; firstSeekableStream = current; } @@ -169,16 +167,17 @@ namespace SharpCompress.IO if (lastBufferingIndex != -1) { var bufferingStream = stack[lastBufferingIndex]; - if (position >= 0 && position < bufferingStream.BufferSize) + var targetBufferPosition = + position - bufferingStream.GetPosition() + bufferingStream.BufferPosition; + + if (targetBufferPosition >= 0 && targetBufferPosition <= bufferingStream.BufferSize) { - bufferingStream.BufferPosition = (int)position; + bufferingStream.BufferPosition = (int)targetBufferPosition; return position; } - else - { - // If position is not in buffer, reset buffer and proceed as non-buffering - bufferingStream.BufferPosition = 0; - } + + // If position is not in buffer, reset buffer and proceed as non-buffering + bufferingStream.BufferPosition = 0; // Continue to seek as if no buffer is present } diff --git a/src/SharpCompress/IO/SharpCompressStream.cs b/src/SharpCompress/IO/SharpCompressStream.cs index 1dadce4e..00c0ada2 100644 --- a/src/SharpCompress/IO/SharpCompressStream.cs +++ b/src/SharpCompress/IO/SharpCompressStream.cs @@ -79,7 +79,7 @@ public class SharpCompressStream : Stream, IStreamStack { if (value < 0 || value > _bufferedLength) throw new ArgumentOutOfRangeException(nameof(value)); - _internalPosition = value; + _internalPosition = _internalPosition - _bufferPosition + value; _bufferPosition = value; ValidateBufferState(); // Add here } @@ -291,7 +291,7 @@ public class SharpCompressStream : Stream, IStreamStack long bufferPos = _internalPosition - _bufferPosition; - if (targetPos >= bufferPos && targetPos < bufferPos + _bufferedLength) + if (targetPos >= bufferPos && targetPos <= bufferPos + _bufferedLength) { _bufferPosition = (int)(targetPos - bufferPos); //repoint within the buffer _internalPosition = targetPos; diff --git a/tests/SharpCompress.Test/Streams/RewindableStreamTest.cs b/tests/SharpCompress.Test/Streams/RewindableStreamTest.cs index d83ed86c..37580df9 100644 --- a/tests/SharpCompress.Test/Streams/RewindableStreamTest.cs +++ b/tests/SharpCompress.Test/Streams/RewindableStreamTest.cs @@ -85,4 +85,22 @@ public class RewindableStreamTest Assert.Equal(6, br.ReadInt32()); Assert.Equal(7, br.ReadInt32()); } + + [Fact] + public void TestSmallBuffer() + { + var ms = new MemoryStream(); + var testData = new byte[100]; + for (byte i = 0; i < 100; i++) + { + testData[i] = i; + } + ms.Write(testData); + ms.Position = 0; + using var stream = new SharpCompressStream(ms, bufferSize: 64); + var br = new BinaryReader(stream); + stream.StackSeek(100); + stream.StackSeek(10); + Assert.Equal(10, br.ReadByte()); + } }