Skip to content

Commit

Permalink
Return a bounded substream when data descriptors are used in seekable…
Browse files Browse the repository at this point in the history
… zips
  • Loading branch information
DannyBoyk committed Jun 4, 2019
1 parent cfd6df9 commit af264cd
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 1 deletion.
12 changes: 12 additions & 0 deletions src/SharpCompress/Common/Zip/SeekableZipFilePart.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
using System.IO;
using SharpCompress.Common.Zip.Headers;
using SharpCompress.IO;

namespace SharpCompress.Common.Zip
{
internal class SeekableZipFilePart : ZipFilePart
{
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()
Expand All @@ -36,6 +39,15 @@ private void LoadLocalHeader()
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;
}
}
Expand Down
21 changes: 20 additions & 1 deletion tests/SharpCompress.Test/Zip/ZipArchiveTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -536,5 +536,24 @@ public void Zip_BadLocalExtra_Read()
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);
}
}
}
}
}
Binary file not shown.

0 comments on commit af264cd

Please sign in to comment.