From af264cdc58c9d076bf83477cbdbfe7a5dad282b7 Mon Sep 17 00:00:00 2001 From: Daniel Nash Date: Mon, 3 Jun 2019 13:18:34 -0400 Subject: [PATCH] Return a bounded substream when data descriptors are used in seekable zips --- .../Common/Zip/SeekableZipFilePart.cs | 12 ++++++++++ .../SharpCompress.Test/Zip/ZipArchiveTests.cs | 21 +++++++++++++++++- .../Archives/Zip.none.datadescriptors.zip | Bin 0 -> 744 bytes 3 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 tests/TestArchives/Archives/Zip.none.datadescriptors.zip diff --git a/src/SharpCompress/Common/Zip/SeekableZipFilePart.cs b/src/SharpCompress/Common/Zip/SeekableZipFilePart.cs index d06b34aa..c7ac7de7 100644 --- a/src/SharpCompress/Common/Zip/SeekableZipFilePart.cs +++ b/src/SharpCompress/Common/Zip/SeekableZipFilePart.cs @@ -1,5 +1,6 @@ using System.IO; using SharpCompress.Common.Zip.Headers; +using SharpCompress.IO; namespace SharpCompress.Common.Zip { @@ -7,11 +8,13 @@ namespace SharpCompress.Common.Zip { private bool _isLocalHeaderLoaded; private readonly SeekableZipHeaderFactory _headerFactory; + private readonly DirectoryEntryHeader _directoryEntryHeader; internal SeekableZipFilePart(SeekableZipHeaderFactory headerFactory, DirectoryEntryHeader header, Stream stream) : base(header, stream) { _headerFactory = headerFactory; + _directoryEntryHeader = header; } internal override Stream GetCompressedStream() @@ -36,6 +39,15 @@ namespace SharpCompress.Common.Zip protected override Stream CreateBaseStream() { BaseStream.Position = Header.DataStartPosition.Value; + + if ((Header.CompressedSize == 0) + && FlagUtility.HasFlag(Header.Flags, HeaderFlags.UsePostDataDescriptor) + && (_directoryEntryHeader?.HasData == true) + && (_directoryEntryHeader?.CompressedSize != 0)) + { + return new ReadOnlySubStream(BaseStream, _directoryEntryHeader.CompressedSize); + } + return BaseStream; } } diff --git a/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs b/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs index f76b380d..5238d5df 100644 --- a/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs +++ b/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs @@ -536,5 +536,24 @@ namespace SharpCompress.Test.Zip Assert.Null(ex); } } - } + + [Fact] + public void Zip_NoCompression_DataDescriptors_Read() + { + string zipPath = Path.Combine(TEST_ARCHIVES_PATH, "Zip.none.datadescriptors.zip"); + + using (ZipArchive za = ZipArchive.Open(zipPath)) + { + var firstEntry = za.Entries.First(x => x.Key == "first.txt"); + var buffer = new byte[4096]; + + using (var memoryStream = new MemoryStream()) + using (var firstStream = firstEntry.OpenEntryStream()) + { + firstStream.CopyTo(memoryStream); + Assert.Equal(199, memoryStream.Length); + } + } + } + } } diff --git a/tests/TestArchives/Archives/Zip.none.datadescriptors.zip b/tests/TestArchives/Archives/Zip.none.datadescriptors.zip new file mode 100644 index 0000000000000000000000000000000000000000..62d72a4f4b0015d2ba8116e1a12ec5edc66587ff GIT binary patch literal 744 zcmWIWW@h1H;9$T6oD4DyX_-aEC3+68HVE2_p9%W!)0O0^{MkYCCNTS&ku+|Sb&^Q?+;3;WIBZ!HVgjgX-2rc;_8@D51tsk;g lTqwp#F*2ZpJ1YY-DBLm3V`T$b%*4RNFrR^e!I%le0{{_W)B6Ab literal 0 HcmV?d00001