mirror of
https://github.com/adamhathcock/sharpcompress.git
synced 2026-02-13 05:25:00 +00:00
Compare commits
6 Commits
adam/write
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
165239c971 | ||
|
|
d68b9d6a86 | ||
|
|
359b1093bc | ||
|
|
ebb8f16e44 | ||
|
|
c7dac12cd9 | ||
|
|
a505808549 |
@@ -10,6 +10,10 @@ public class ZipEntry : Entry
|
||||
{
|
||||
private readonly ZipFilePart? _filePart;
|
||||
|
||||
// WinZip AES extra data constants
|
||||
private const int MinimumWinZipAesExtraDataLength = 7;
|
||||
private const int WinZipAesCompressionMethodOffset = 5;
|
||||
|
||||
internal ZipEntry(ZipFilePart? filePart, IReaderOptions readerOptions)
|
||||
: base(readerOptions)
|
||||
{
|
||||
@@ -33,24 +37,54 @@ public class ZipEntry : Entry
|
||||
CreatedTime = times?.UnicodeTimes.Item3;
|
||||
}
|
||||
|
||||
public override CompressionType CompressionType =>
|
||||
_filePart?.Header.CompressionMethod switch
|
||||
public override CompressionType CompressionType
|
||||
{
|
||||
get
|
||||
{
|
||||
ZipCompressionMethod.BZip2 => CompressionType.BZip2,
|
||||
ZipCompressionMethod.Deflate => CompressionType.Deflate,
|
||||
ZipCompressionMethod.Deflate64 => CompressionType.Deflate64,
|
||||
ZipCompressionMethod.LZMA => CompressionType.LZMA,
|
||||
ZipCompressionMethod.PPMd => CompressionType.PPMd,
|
||||
ZipCompressionMethod.None => CompressionType.None,
|
||||
ZipCompressionMethod.Shrink => CompressionType.Shrink,
|
||||
ZipCompressionMethod.Reduce1 => CompressionType.Reduce1,
|
||||
ZipCompressionMethod.Reduce2 => CompressionType.Reduce2,
|
||||
ZipCompressionMethod.Reduce3 => CompressionType.Reduce3,
|
||||
ZipCompressionMethod.Reduce4 => CompressionType.Reduce4,
|
||||
ZipCompressionMethod.Explode => CompressionType.Explode,
|
||||
ZipCompressionMethod.ZStandard => CompressionType.ZStandard,
|
||||
_ => CompressionType.Unknown,
|
||||
};
|
||||
var compressionMethod = GetActualCompressionMethod();
|
||||
return compressionMethod switch
|
||||
{
|
||||
ZipCompressionMethod.BZip2 => CompressionType.BZip2,
|
||||
ZipCompressionMethod.Deflate => CompressionType.Deflate,
|
||||
ZipCompressionMethod.Deflate64 => CompressionType.Deflate64,
|
||||
ZipCompressionMethod.LZMA => CompressionType.LZMA,
|
||||
ZipCompressionMethod.PPMd => CompressionType.PPMd,
|
||||
ZipCompressionMethod.None => CompressionType.None,
|
||||
ZipCompressionMethod.Shrink => CompressionType.Shrink,
|
||||
ZipCompressionMethod.Reduce1 => CompressionType.Reduce1,
|
||||
ZipCompressionMethod.Reduce2 => CompressionType.Reduce2,
|
||||
ZipCompressionMethod.Reduce3 => CompressionType.Reduce3,
|
||||
ZipCompressionMethod.Reduce4 => CompressionType.Reduce4,
|
||||
ZipCompressionMethod.Explode => CompressionType.Explode,
|
||||
ZipCompressionMethod.ZStandard => CompressionType.ZStandard,
|
||||
_ => CompressionType.Unknown,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private ZipCompressionMethod GetActualCompressionMethod()
|
||||
{
|
||||
if (_filePart?.Header.CompressionMethod != ZipCompressionMethod.WinzipAes)
|
||||
{
|
||||
return _filePart?.Header.CompressionMethod ?? ZipCompressionMethod.None;
|
||||
}
|
||||
|
||||
// For WinZip AES, the actual compression method is stored in the extra data
|
||||
var aesExtraData = _filePart.Header.Extra.FirstOrDefault(x =>
|
||||
x.Type == ExtraDataType.WinZipAes
|
||||
);
|
||||
|
||||
if (aesExtraData is null || aesExtraData.DataBytes.Length < MinimumWinZipAesExtraDataLength)
|
||||
{
|
||||
return ZipCompressionMethod.WinzipAes;
|
||||
}
|
||||
|
||||
// The compression method is at offset 5 in the extra data
|
||||
return (ZipCompressionMethod)
|
||||
System.Buffers.Binary.BinaryPrimitives.ReadUInt16LittleEndian(
|
||||
aesExtraData.DataBytes.AsSpan(WinZipAesCompressionMethodOffset)
|
||||
);
|
||||
}
|
||||
|
||||
public override long Crc => _filePart?.Header.Crc ?? 0;
|
||||
|
||||
|
||||
@@ -491,6 +491,56 @@ public class ZipArchiveTests : ArchiveTests
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Zip_WinzipAES_CompressionType()
|
||||
{
|
||||
// Test that WinZip AES encrypted entries correctly report their compression type
|
||||
using var deflateArchive = ZipArchive.OpenArchive(
|
||||
Path.Combine(TEST_ARCHIVES_PATH, "Zip.deflate.WinzipAES.zip"),
|
||||
new ReaderOptions { Password = "test" }
|
||||
);
|
||||
foreach (var entry in deflateArchive.Entries.Where(x => !x.IsDirectory))
|
||||
{
|
||||
Assert.True(entry.IsEncrypted);
|
||||
Assert.Equal(CompressionType.Deflate, entry.CompressionType);
|
||||
}
|
||||
|
||||
using var lzmaArchive = ZipArchive.OpenArchive(
|
||||
Path.Combine(TEST_ARCHIVES_PATH, "Zip.lzma.WinzipAES.zip"),
|
||||
new ReaderOptions { Password = "test" }
|
||||
);
|
||||
foreach (var entry in lzmaArchive.Entries.Where(x => !x.IsDirectory))
|
||||
{
|
||||
Assert.True(entry.IsEncrypted);
|
||||
Assert.Equal(CompressionType.LZMA, entry.CompressionType);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Zip_Pkware_CompressionType()
|
||||
{
|
||||
// Test that Pkware encrypted entries correctly report their compression type
|
||||
using var deflateArchive = ZipArchive.OpenArchive(
|
||||
Path.Combine(TEST_ARCHIVES_PATH, "Zip.deflate.pkware.zip"),
|
||||
new ReaderOptions { Password = "test" }
|
||||
);
|
||||
foreach (var entry in deflateArchive.Entries.Where(x => !x.IsDirectory))
|
||||
{
|
||||
Assert.True(entry.IsEncrypted);
|
||||
Assert.Equal(CompressionType.Deflate, entry.CompressionType);
|
||||
}
|
||||
|
||||
using var bzip2Archive = ZipArchive.OpenArchive(
|
||||
Path.Combine(TEST_ARCHIVES_PATH, "Zip.bzip2.pkware.zip"),
|
||||
new ReaderOptions { Password = "test" }
|
||||
);
|
||||
foreach (var entry in bzip2Archive.Entries.Where(x => !x.IsDirectory))
|
||||
{
|
||||
Assert.True(entry.IsEncrypted);
|
||||
Assert.Equal(CompressionType.BZip2, entry.CompressionType);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Zip_Read_Volume_Comment()
|
||||
{
|
||||
|
||||
@@ -224,7 +224,7 @@ public class ZipReaderAsyncTests : ReaderTests
|
||||
{
|
||||
if (!reader.Entry.IsDirectory)
|
||||
{
|
||||
Assert.Equal(CompressionType.Unknown, reader.Entry.CompressionType);
|
||||
Assert.Equal(CompressionType.LZMA, reader.Entry.CompressionType);
|
||||
await reader.WriteEntryToDirectoryAsync(SCRATCH_FILES_PATH);
|
||||
}
|
||||
}
|
||||
@@ -252,7 +252,7 @@ public class ZipReaderAsyncTests : ReaderTests
|
||||
{
|
||||
if (!reader.Entry.IsDirectory)
|
||||
{
|
||||
Assert.Equal(CompressionType.Unknown, reader.Entry.CompressionType);
|
||||
Assert.Equal(CompressionType.Deflate, reader.Entry.CompressionType);
|
||||
await reader.WriteEntryToDirectoryAsync(SCRATCH_FILES_PATH);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,7 +201,7 @@ public class ZipReaderTests : ReaderTests
|
||||
{
|
||||
if (!reader.Entry.IsDirectory)
|
||||
{
|
||||
Assert.Equal(CompressionType.Unknown, reader.Entry.CompressionType);
|
||||
Assert.Equal(CompressionType.LZMA, reader.Entry.CompressionType);
|
||||
reader.WriteEntryToDirectory(SCRATCH_FILES_PATH);
|
||||
}
|
||||
}
|
||||
@@ -223,7 +223,7 @@ public class ZipReaderTests : ReaderTests
|
||||
{
|
||||
if (!reader.Entry.IsDirectory)
|
||||
{
|
||||
Assert.Equal(CompressionType.Unknown, reader.Entry.CompressionType);
|
||||
Assert.Equal(CompressionType.Deflate, reader.Entry.CompressionType);
|
||||
reader.WriteEntryToDirectory(SCRATCH_FILES_PATH);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user