Skip to content

Commit

Permalink
Merge pull request #689 from Erior/master
Browse files Browse the repository at this point in the history
64bit datadescriptors
  • Loading branch information
adamhathcock authored Sep 6, 2022
2 parents f1d8fad + 191bb9d commit 3ae7ba8
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 9 deletions.
21 changes: 19 additions & 2 deletions src/SharpCompress/Common/Zip/StreamingZipFilePart.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ internal BinaryReader FixStreamedFileLocation(ref RewindableStream rewindableStr
{
_decompressionStream.Skip();

// If we had TotalIn / TotalOut we could have used them
Header.CompressedSize = _decompressionStream.Position;

if (_decompressionStream is DeflateStream deflateStream)
{
rewindableStream.Rewind(deflateStream.InputBuffer);
Expand All @@ -66,12 +69,26 @@ internal BinaryReader FixStreamedFileLocation(ref RewindableStream rewindableStr
br.ReadUInt32(); // CRC32
var compressed_size = br.ReadUInt32();
var uncompressed_size = br.ReadUInt32();
var uncompressed_64bit = br.ReadInt64();

long test_64bit = (long)uncompressed_size << 32 | (long)compressed_size;

if( test_64bit == size && test_64bit == uncompressed_64bit )
{
Header.CompressedSize = test_64bit;
Header.UncompressedSize = uncompressed_64bit;
rewindableStream.Position -= 24;
break;
}

if (compressed_size == size && compressed_size == uncompressed_size )
{
rewindableStream.Position -= 16;
Header.CompressedSize = compressed_size;
Header.UncompressedSize = uncompressed_size;
rewindableStream.Position -= 24;
break;
}
rewindableStream.Position -= 12;
rewindableStream.Position -= 20;
}
}

Expand Down
33 changes: 28 additions & 5 deletions src/SharpCompress/Common/Zip/StreamingZipHeaderFactory.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
using System.IO;
using SharpCompress.Common.Zip.Headers;
using SharpCompress.IO;
Expand Down Expand Up @@ -28,6 +28,7 @@ internal IEnumerable<ZipHeader> ReadStreamHeader(Stream stream)
{
ZipHeader? header;
BinaryReader reader = new BinaryReader(rewindableStream);
uint headerBytes = 0;
if (_lastEntryHeader != null &&
(FlagUtility.HasFlag(_lastEntryHeader.Flags, HeaderFlags.UsePostDataDescriptor) || _lastEntryHeader.IsZip64))
{
Expand All @@ -39,15 +40,37 @@ internal IEnumerable<ZipHeader> ReadStreamHeader(Stream stream)
crc = reader.ReadUInt32();
}
_lastEntryHeader.Crc = crc;
_lastEntryHeader.CompressedSize = reader.ReadUInt32();
_lastEntryHeader.UncompressedSize = reader.ReadUInt32();

// The DataDescriptor can be either 64bit or 32bit
var compressed_size = reader.ReadUInt32();
var uncompressed_size = reader.ReadUInt32();

// Check if we have header or 64bit DataDescriptor
headerBytes = reader.ReadUInt32();
bool test_header = !(headerBytes == 0x04034b50 || headerBytes == 0x02014b50);

long test_64bit = (long)uncompressed_size << 32 | (long)compressed_size;
if ( test_64bit == _lastEntryHeader.CompressedSize && test_header )
{
_lastEntryHeader.UncompressedSize = (long)reader.ReadUInt32() << 32 | (long)headerBytes;
headerBytes = reader.ReadUInt32();
}
else
{
_lastEntryHeader.UncompressedSize = uncompressed_size;
}

if (pos.HasValue)
{
_lastEntryHeader.DataStartPosition = pos - _lastEntryHeader.CompressedSize;
}
}
else
{
headerBytes = reader.ReadUInt32();
}

_lastEntryHeader = null;
uint headerBytes = reader.ReadUInt32();
header = ReadHeader(headerBytes, reader);
if (header is null)
{
Expand Down Expand Up @@ -86,4 +109,4 @@ internal IEnumerable<ZipHeader> ReadStreamHeader(Stream stream)
}
}
}
}
}
23 changes: 21 additions & 2 deletions tests/SharpCompress.Test/Zip/ZipReaderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -401,8 +401,6 @@ public void Issue_685()
}
}



[Fact]
public void Zip_Uncompressed_Skip_All()
{
Expand All @@ -415,5 +413,26 @@ public void Zip_Uncompressed_Skip_All()
}
}
}

[Fact]
public void Zip_Uncompressed_64bit()
{
var zipPath = Path.Combine(TEST_ARCHIVES_PATH, "64bitstream.zip.7z");
using (var stream = File.Open(zipPath, FileMode.Open, FileAccess.Read))
{
var archive = Archives.ArchiveFactory.Open(stream);
var reader = archive.ExtractAllEntries();
reader.MoveToNextEntry();
var zipReader = ZipReader.Open(reader.OpenEntryStream());
var x = 0;
while (zipReader.MoveToNextEntry())
{
x++;
}

Assert.Equal(4, x);
}
}

}
}
Binary file added tests/TestArchives/Archives/64bitstream.zip.7z
Binary file not shown.

0 comments on commit 3ae7ba8

Please sign in to comment.