From bd8ba7b8540464bfcdc0d85fbdf5194ab893705b Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Fri, 12 Aug 2016 11:56:49 +0100 Subject: [PATCH] Test with ForwardOnlyStream. RewindableStream shouldn't corrupt a ForwardOnlyStream (#161) --- .../Common/Zip/StreamingZipHeaderFactory.cs | 7 +- src/SharpCompress/IO/RewindableStream.cs | 5 +- test/SharpCompress.Test/ForwardOnlyStream.cs | 64 +++++++++++++++++++ test/SharpCompress.Test/ReaderTests.cs | 2 +- 4 files changed, 71 insertions(+), 7 deletions(-) create mode 100644 test/SharpCompress.Test/ForwardOnlyStream.cs diff --git a/src/SharpCompress/Common/Zip/StreamingZipHeaderFactory.cs b/src/SharpCompress/Common/Zip/StreamingZipHeaderFactory.cs index 7e736cef..7d15ea21 100644 --- a/src/SharpCompress/Common/Zip/StreamingZipHeaderFactory.cs +++ b/src/SharpCompress/Common/Zip/StreamingZipHeaderFactory.cs @@ -31,7 +31,7 @@ namespace SharpCompress.Common.Zip FlagUtility.HasFlag(lastEntryHeader.Flags, HeaderFlags.UsePostDataDescriptor)) { reader = (lastEntryHeader.Part as StreamingZipFilePart).FixStreamedFileLocation(ref rewindableStream); - long pos = rewindableStream.Position; + long? pos = rewindableStream.CanSeek ? (long?)rewindableStream.Position : null; uint crc = reader.ReadUInt32(); if (crc == POST_DATA_DESCRIPTOR) { @@ -40,7 +40,10 @@ namespace SharpCompress.Common.Zip lastEntryHeader.Crc = crc; lastEntryHeader.CompressedSize = reader.ReadUInt32(); lastEntryHeader.UncompressedSize = reader.ReadUInt32(); - lastEntryHeader.DataStartPosition = pos - lastEntryHeader.CompressedSize; + if (pos.HasValue) + { + lastEntryHeader.DataStartPosition = pos - lastEntryHeader.CompressedSize; + } } lastEntryHeader = null; uint headerBytes = reader.ReadUInt32(); diff --git a/src/SharpCompress/IO/RewindableStream.cs b/src/SharpCompress/IO/RewindableStream.cs index 054888f7..14e18bd5 100644 --- a/src/SharpCompress/IO/RewindableStream.cs +++ b/src/SharpCompress/IO/RewindableStream.cs @@ -72,10 +72,7 @@ namespace SharpCompress.IO get { return true; } } - public override bool CanSeek - { - get { return false; } - } + public override bool CanSeek => stream.CanSeek; public override bool CanWrite { diff --git a/test/SharpCompress.Test/ForwardOnlyStream.cs b/test/SharpCompress.Test/ForwardOnlyStream.cs new file mode 100644 index 00000000..53f4a99a --- /dev/null +++ b/test/SharpCompress.Test/ForwardOnlyStream.cs @@ -0,0 +1,64 @@ +using System; +using System.IO; + +namespace SharpCompress.Test +{ + public class ForwardOnlyStream : Stream + { + private readonly Stream stream; + + public bool IsDisposed { get; private set; } + + public ForwardOnlyStream(Stream stream) + { + this.stream = stream; + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + stream.Dispose(); + IsDisposed = true; + } + + public override bool CanRead => true; + + public override bool CanSeek => false; + public override bool CanWrite => false; + + public override void Flush() + { + throw new NotSupportedException(); + } + + public override long Length + { + get { throw new NotSupportedException(); } + } + + public override long Position + { + get { throw new NotSupportedException(); } + set { throw new NotSupportedException(); } + } + + public override int Read(byte[] buffer, int offset, int count) + { + return stream.Read(buffer, offset, count); + } + + public override long Seek(long offset, SeekOrigin origin) + { + throw new NotSupportedException(); + } + + public override void SetLength(long value) + { + throw new NotSupportedException(); + } + + public override void Write(byte[] buffer, int offset, int count) + {throw new NotSupportedException(); + } + } +} \ No newline at end of file diff --git a/test/SharpCompress.Test/ReaderTests.cs b/test/SharpCompress.Test/ReaderTests.cs index 205c3cbf..eaa2d3fb 100644 --- a/test/SharpCompress.Test/ReaderTests.cs +++ b/test/SharpCompress.Test/ReaderTests.cs @@ -18,7 +18,7 @@ namespace SharpCompress.Test { foreach (var path in testArchives) { - using (Stream stream = File.OpenRead(path)) + using (Stream stream = new ForwardOnlyStream(File.OpenRead(path))) using (IReader reader = ReaderFactory.Open(stream)) { UseReader(this, reader, expectedCompression);