Merge pull request #891 from Morilli/fix-zip-datadescriptor-header

Fix zip entry handling for entries with data descriptors
This commit is contained in:
Adam Hathcock
2025-01-28 08:12:40 +00:00
committed by GitHub
3 changed files with 19 additions and 17 deletions

View File

@@ -1,6 +1,5 @@
using System.IO;
using SharpCompress.Common.Zip.Headers;
using SharpCompress.IO;
namespace SharpCompress.Common.Zip;
@@ -8,18 +7,13 @@ 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;
}
: base(header, stream) => _headerFactory = headerFactory;
internal override Stream GetCompressedStream()
{
@@ -44,16 +38,6 @@ internal class SeekableZipFilePart : ZipFilePart
{
BaseStream.Position = Header.DataStartPosition.NotNull();
if (
(Header.CompressedSize == 0)
&& FlagUtility.HasFlag(Header.Flags, HeaderFlags.UsePostDataDescriptor)
&& _directoryEntryHeader.HasData
&& (_directoryEntryHeader.CompressedSize != 0)
)
{
return new ReadOnlySubStream(BaseStream, _directoryEntryHeader.CompressedSize);
}
return BaseStream;
}
}

View File

@@ -149,6 +149,12 @@ internal sealed class SeekableZipHeaderFactory : ZipHeaderFactory
{
throw new InvalidOperationException();
}
if (FlagUtility.HasFlag(localEntryHeader.Flags, HeaderFlags.UsePostDataDescriptor))
{
localEntryHeader.Crc = directoryEntryHeader.Crc;
localEntryHeader.CompressedSize = directoryEntryHeader.CompressedSize;
localEntryHeader.UncompressedSize = directoryEntryHeader.UncompressedSize;
}
return localEntryHeader;
}
}

View File

@@ -808,4 +808,16 @@ public class ZipArchiveTests : ArchiveTests
Assert.Equal("きょきゅんきゃんきゅ_wav.frq", reader.Entry.Key);
}
}
[Fact]
public void TestDataDescriptorRead()
{
using var archive = ArchiveFactory.Open(
Path.Combine(TEST_ARCHIVES_PATH, "Zip.none.datadescriptors.zip")
);
var firstEntry = archive.Entries.First();
Assert.Equal(199, firstEntry.Size);
using var _ = firstEntry.OpenEntryStream();
Assert.Equal(199, firstEntry.Size);
}
}