From efae8328a9801e9729f2ec54b9a305c3392c055c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Knut=20=C3=98rland?= Date: Thu, 4 Oct 2018 13:05:36 +0200 Subject: [PATCH 1/3] Don't throw an exception when flushing an EntryStream MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From Microsoft docs: “In a class derived from Stream that doesn't support writing, Flush is typically implemented as an empty method to ensure full compatibility with other Stream types since it's valid to flush a read-only stream.” --- src/SharpCompress/Common/EntryStream.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/SharpCompress/Common/EntryStream.cs b/src/SharpCompress/Common/EntryStream.cs index 8d40cabd..086d4173 100644 --- a/src/SharpCompress/Common/EntryStream.cs +++ b/src/SharpCompress/Common/EntryStream.cs @@ -47,10 +47,8 @@ namespace SharpCompress.Common public override bool CanWrite => false; - public override void Flush() - { - throw new NotSupportedException(); - } + public override void Flush() { + } public override long Length => _stream.Length; From 6dd5da48f7fcae7122a66f2eaff15acdd9ef5c4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Knut=20=C3=98rland?= Date: Thu, 4 Oct 2018 13:08:53 +0200 Subject: [PATCH 2/3] Added test that calls EntryStream.Flush() --- .../Mocks/FlushOnDisposeStream.cs | 57 ++++++++++++++++++ .../SharpCompress.Test/Tar/TarReaderTests.cs | 28 ++++++++- .../Archives/Tar.ContainsTarGz.tar | Bin 0 -> 10240 bytes 3 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 tests/SharpCompress.Test/Mocks/FlushOnDisposeStream.cs create mode 100644 tests/TestArchives/Archives/Tar.ContainsTarGz.tar diff --git a/tests/SharpCompress.Test/Mocks/FlushOnDisposeStream.cs b/tests/SharpCompress.Test/Mocks/FlushOnDisposeStream.cs new file mode 100644 index 00000000..d85fb033 --- /dev/null +++ b/tests/SharpCompress.Test/Mocks/FlushOnDisposeStream.cs @@ -0,0 +1,57 @@ +using System; +using System.IO; + +namespace SharpCompress.Test.Mocks +{ + // This is a simplified version of CryptoStream that always flushes the inner stream on Dispose to trigger an error in EntryStream + // CryptoStream doesn't always trigger the Flush, so this class is used instead + // See https://referencesource.microsoft.com/#mscorlib/system/security/cryptography/cryptostream.cs,141 + + public class FlushOnDisposeStream : Stream, IDisposable + { + private Stream inner; + + public FlushOnDisposeStream(Stream innerStream) { + this.inner = innerStream; + } + + public override bool CanRead => this.inner.CanRead; + + public override bool CanSeek => false; + + public override bool CanWrite => false; + + public override long Length => this.inner.Length; + + public override long Position { get => this.inner.Position; set => this.inner.Position = value; } + + public override void Flush() { + throw new NotImplementedException(); + } + + public override int Read(byte[] buffer, int offset, int count) { + return this.inner.Read(buffer, offset, count); + } + + public override long Seek(long offset, SeekOrigin origin) { + throw new NotImplementedException(); + } + + public override void SetLength(long value) { + throw new NotImplementedException(); + } + + public override void Write(byte[] buffer, int offset, int count) { + throw new NotImplementedException(); + } + + protected override void Dispose(bool disposing) { + if(disposing) { + this.inner.Flush(); + this.inner.Close(); + } + + base.Dispose(disposing); + } + } +} diff --git a/tests/SharpCompress.Test/Tar/TarReaderTests.cs b/tests/SharpCompress.Test/Tar/TarReaderTests.cs index acd73eec..c155de3d 100644 --- a/tests/SharpCompress.Test/Tar/TarReaderTests.cs +++ b/tests/SharpCompress.Test/Tar/TarReaderTests.cs @@ -160,5 +160,31 @@ namespace SharpCompress.Test.Tar Assert.True(reader.ArchiveType == ArchiveType.Tar); } } - } + + [Fact] + public void Tar_With_TarGz_With_Flushed_EntryStream() + { + string archiveFullPath = Path.Combine(TEST_ARCHIVES_PATH, "Tar.ContainsTarGz.tar"); + using(Stream stream = File.OpenRead(archiveFullPath)) + using(IReader reader = ReaderFactory.Open(stream)) + { + Assert.True(reader.MoveToNextEntry()); + Assert.Equal("inner.tar.gz", reader.Entry.Key); + + using(var entryStream = reader.OpenEntryStream()) { + + using(FlushOnDisposeStream flushingStream = new FlushOnDisposeStream(entryStream)) { + + // Extract inner.tar.gz + using(var innerReader = ReaderFactory.Open(flushingStream)) { + + Assert.True(innerReader.MoveToNextEntry()); + Assert.Equal("test", innerReader.Entry.Key); + + } + } + } + } + } + } } diff --git a/tests/TestArchives/Archives/Tar.ContainsTarGz.tar b/tests/TestArchives/Archives/Tar.ContainsTarGz.tar new file mode 100644 index 0000000000000000000000000000000000000000..697060bcaf1b395a887a517e6252028d469309aa GIT binary patch literal 10240 zcmd1I%S$cND@iQUORr*}5il??FfcPQVF1zQW~N};zzD(zi5Z$3GZ-2ho0=M%nV5jY z4UG(q%@`C6XyhIgV@r!m5{ncR7`*dJOHd@xIK?H2X=!L;!+IK8Fo-u&p;?Oc~; zwI*DQe&G_`oAv0++YN_zO-U^Cdp0MZe`BwvZ#+xw>h=Hg|Mj5;lFc?|F~jUG1`Sl< zQQl|>jE2By2#kinXb6mkz-S1JhQMeDjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kin vXb6mkz-S1JhQMeDjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kgRi6H<0a#Be$ literal 0 HcmV?d00001 From 53ad00cdc49a4a266b17d73b5bb9901bb7567098 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Knut=20=C3=98rland?= Date: Thu, 4 Oct 2018 13:13:14 +0200 Subject: [PATCH 3/3] Use soft tabs --- src/SharpCompress/Common/EntryStream.cs | 2 +- .../Mocks/FlushOnDisposeStream.cs | 74 +++++++++---------- .../SharpCompress.Test/Tar/TarReaderTests.cs | 42 +++++------ 3 files changed, 59 insertions(+), 59 deletions(-) diff --git a/src/SharpCompress/Common/EntryStream.cs b/src/SharpCompress/Common/EntryStream.cs index 086d4173..fe7fd3e7 100644 --- a/src/SharpCompress/Common/EntryStream.cs +++ b/src/SharpCompress/Common/EntryStream.cs @@ -48,7 +48,7 @@ namespace SharpCompress.Common public override bool CanWrite => false; public override void Flush() { - } + } public override long Length => _stream.Length; diff --git a/tests/SharpCompress.Test/Mocks/FlushOnDisposeStream.cs b/tests/SharpCompress.Test/Mocks/FlushOnDisposeStream.cs index d85fb033..6e0b4131 100644 --- a/tests/SharpCompress.Test/Mocks/FlushOnDisposeStream.cs +++ b/tests/SharpCompress.Test/Mocks/FlushOnDisposeStream.cs @@ -3,55 +3,55 @@ using System.IO; namespace SharpCompress.Test.Mocks { - // This is a simplified version of CryptoStream that always flushes the inner stream on Dispose to trigger an error in EntryStream - // CryptoStream doesn't always trigger the Flush, so this class is used instead - // See https://referencesource.microsoft.com/#mscorlib/system/security/cryptography/cryptostream.cs,141 + // This is a simplified version of CryptoStream that always flushes the inner stream on Dispose to trigger an error in EntryStream + // CryptoStream doesn't always trigger the Flush, so this class is used instead + // See https://referencesource.microsoft.com/#mscorlib/system/security/cryptography/cryptostream.cs,141 - public class FlushOnDisposeStream : Stream, IDisposable - { - private Stream inner; + public class FlushOnDisposeStream : Stream, IDisposable + { + private Stream inner; - public FlushOnDisposeStream(Stream innerStream) { - this.inner = innerStream; - } + public FlushOnDisposeStream(Stream innerStream) { + this.inner = innerStream; + } - public override bool CanRead => this.inner.CanRead; + public override bool CanRead => this.inner.CanRead; - public override bool CanSeek => false; + public override bool CanSeek => false; - public override bool CanWrite => false; + public override bool CanWrite => false; - public override long Length => this.inner.Length; + public override long Length => this.inner.Length; - public override long Position { get => this.inner.Position; set => this.inner.Position = value; } + public override long Position { get => this.inner.Position; set => this.inner.Position = value; } - public override void Flush() { - throw new NotImplementedException(); - } + public override void Flush() { + throw new NotImplementedException(); + } - public override int Read(byte[] buffer, int offset, int count) { - return this.inner.Read(buffer, offset, count); - } + public override int Read(byte[] buffer, int offset, int count) { + return this.inner.Read(buffer, offset, count); + } - public override long Seek(long offset, SeekOrigin origin) { - throw new NotImplementedException(); - } + public override long Seek(long offset, SeekOrigin origin) { + throw new NotImplementedException(); + } - public override void SetLength(long value) { - throw new NotImplementedException(); - } + public override void SetLength(long value) { + throw new NotImplementedException(); + } - public override void Write(byte[] buffer, int offset, int count) { - throw new NotImplementedException(); - } + public override void Write(byte[] buffer, int offset, int count) { + throw new NotImplementedException(); + } - protected override void Dispose(bool disposing) { - if(disposing) { - this.inner.Flush(); - this.inner.Close(); - } + protected override void Dispose(bool disposing) { + if(disposing) { + this.inner.Flush(); + this.inner.Close(); + } - base.Dispose(disposing); - } - } + base.Dispose(disposing); + } + } } diff --git a/tests/SharpCompress.Test/Tar/TarReaderTests.cs b/tests/SharpCompress.Test/Tar/TarReaderTests.cs index c155de3d..10c7ee19 100644 --- a/tests/SharpCompress.Test/Tar/TarReaderTests.cs +++ b/tests/SharpCompress.Test/Tar/TarReaderTests.cs @@ -161,30 +161,30 @@ namespace SharpCompress.Test.Tar } } - [Fact] - public void Tar_With_TarGz_With_Flushed_EntryStream() - { - string archiveFullPath = Path.Combine(TEST_ARCHIVES_PATH, "Tar.ContainsTarGz.tar"); - using(Stream stream = File.OpenRead(archiveFullPath)) - using(IReader reader = ReaderFactory.Open(stream)) - { - Assert.True(reader.MoveToNextEntry()); - Assert.Equal("inner.tar.gz", reader.Entry.Key); + [Fact] + public void Tar_With_TarGz_With_Flushed_EntryStream() + { + string archiveFullPath = Path.Combine(TEST_ARCHIVES_PATH, "Tar.ContainsTarGz.tar"); + using(Stream stream = File.OpenRead(archiveFullPath)) + using(IReader reader = ReaderFactory.Open(stream)) + { + Assert.True(reader.MoveToNextEntry()); + Assert.Equal("inner.tar.gz", reader.Entry.Key); - using(var entryStream = reader.OpenEntryStream()) { + using(var entryStream = reader.OpenEntryStream()) { - using(FlushOnDisposeStream flushingStream = new FlushOnDisposeStream(entryStream)) { + using(FlushOnDisposeStream flushingStream = new FlushOnDisposeStream(entryStream)) { - // Extract inner.tar.gz - using(var innerReader = ReaderFactory.Open(flushingStream)) { + // Extract inner.tar.gz + using(var innerReader = ReaderFactory.Open(flushingStream)) { - Assert.True(innerReader.MoveToNextEntry()); - Assert.Equal("test", innerReader.Entry.Key); + Assert.True(innerReader.MoveToNextEntry()); + Assert.Equal("test", innerReader.Entry.Key); - } - } - } - } - } - } + } + } + } + } + } + } }