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 00000000..62d72a4f Binary files /dev/null and b/tests/TestArchives/Archives/Zip.none.datadescriptors.zip differ