mirror of
https://github.com/adamhathcock/sharpcompress.git
synced 2026-09-22 15:04:43 +00:00
64bit DataDescriptor
This commit is contained in:
@@ -47,6 +47,9 @@ namespace SharpCompress.Common.Zip
|
||||
{
|
||||
_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);
|
||||
@@ -66,12 +69,26 @@ namespace SharpCompress.Common.Zip
|
||||
br.ReadUInt32(); // CRC32
|
||||
var compressed_size = br.ReadUInt32();
|
||||
var uncompressed_size = br.ReadUInt32();
|
||||
if (compressed_size == size && compressed_size == uncompressed_size )
|
||||
var uncompressed_64bit = br.ReadInt64();
|
||||
|
||||
long test_64bit = (long)uncompressed_size << 32 | (long)compressed_size;
|
||||
|
||||
if( test_64bit == size && test_64bit == uncompressed_64bit )
|
||||
{
|
||||
rewindableStream.Position -= 16;
|
||||
Header.CompressedSize = test_64bit;
|
||||
Header.UncompressedSize = uncompressed_64bit;
|
||||
rewindableStream.Position -= 24;
|
||||
break;
|
||||
}
|
||||
rewindableStream.Position -= 12;
|
||||
|
||||
if (compressed_size == size && compressed_size == uncompressed_size )
|
||||
{
|
||||
Header.CompressedSize = compressed_size;
|
||||
Header.UncompressedSize = uncompressed_size;
|
||||
rewindableStream.Position -= 24;
|
||||
break;
|
||||
}
|
||||
rewindableStream.Position -= 20;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using SharpCompress.Common.Zip.Headers;
|
||||
using SharpCompress.IO;
|
||||
@@ -28,6 +28,7 @@ namespace SharpCompress.Common.Zip
|
||||
{
|
||||
ZipHeader? header;
|
||||
BinaryReader reader = new BinaryReader(rewindableStream);
|
||||
uint headerBytes = 0;
|
||||
if (_lastEntryHeader != null &&
|
||||
(FlagUtility.HasFlag(_lastEntryHeader.Flags, HeaderFlags.UsePostDataDescriptor) || _lastEntryHeader.IsZip64))
|
||||
{
|
||||
@@ -39,15 +40,37 @@ namespace SharpCompress.Common.Zip
|
||||
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)
|
||||
{
|
||||
@@ -86,4 +109,4 @@ namespace SharpCompress.Common.Zip
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,9 +143,11 @@ namespace SharpCompress.IO
|
||||
|
||||
if (!IsVolumes && count != 0 && Current.Position == Current.Length)
|
||||
{
|
||||
_prevSize += Current.Length;
|
||||
var length = Current.Length;
|
||||
|
||||
if (!SetStream(_stream + 1)) //will load next file if present
|
||||
break;
|
||||
_prevSize += length;
|
||||
Current.Seek(0, SeekOrigin.Begin);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -401,8 +401,6 @@ namespace SharpCompress.Test.Zip
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
[Fact]
|
||||
public void Zip_Uncompressed_Skip_All()
|
||||
{
|
||||
@@ -415,5 +413,26 @@ namespace SharpCompress.Test.Zip
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
BIN
tests/TestArchives/Archives/64bitstream.zip.7z
Normal file
BIN
tests/TestArchives/Archives/64bitstream.zip.7z
Normal file
Binary file not shown.
Reference in New Issue
Block a user