mirror of
https://github.com/adamhathcock/sharpcompress.git
synced 2026-07-08 18:16:30 +00:00
7Zip and Rar
This commit is contained in:
@@ -71,22 +71,19 @@ public partial class RarArchiveEntry : RarEntry, IArchiveEntry
|
||||
|
||||
public Stream OpenEntryStream()
|
||||
{
|
||||
var readStream = new MultiVolumeReadOnlyStream(Parts.Cast<RarFilePart>());
|
||||
RarStream stream;
|
||||
if (IsRarV3)
|
||||
{
|
||||
stream = new RarStream(
|
||||
archive.UnpackV1.Value,
|
||||
FileHeader,
|
||||
new MultiVolumeReadOnlyStream(Parts.Cast<RarFilePart>())
|
||||
);
|
||||
stream = RarCrcStream.Create(archive.UnpackV1.Value, FileHeader, readStream);
|
||||
}
|
||||
else if (FileHeader.FileCrc?.Length > 5)
|
||||
{
|
||||
stream = RarBLAKE2spStream.Create(archive.UnpackV2017.Value, FileHeader, readStream);
|
||||
}
|
||||
else
|
||||
{
|
||||
stream = new RarStream(
|
||||
archive.UnpackV2017.Value,
|
||||
FileHeader,
|
||||
new MultiVolumeReadOnlyStream(Parts.Cast<RarFilePart>())
|
||||
);
|
||||
stream = RarCrcStream.Create(archive.UnpackV2017.Value, FileHeader, readStream);
|
||||
}
|
||||
|
||||
stream.Initialize();
|
||||
|
||||
@@ -18,6 +18,28 @@ public class SevenZipEntry : Entry
|
||||
|
||||
public override long Crc => FilePart.Header.Crc ?? 0;
|
||||
|
||||
internal override ChecksumDescriptor Checksum
|
||||
{
|
||||
get
|
||||
{
|
||||
if (
|
||||
IsDirectory
|
||||
|| FilePart.Header.IsAnti
|
||||
|| !FilePart.Header.HasStream
|
||||
|| !FilePart.Header.Crc.HasValue
|
||||
)
|
||||
{
|
||||
return default;
|
||||
}
|
||||
|
||||
return new ChecksumDescriptor(
|
||||
ChecksumKind.Crc32,
|
||||
FilePart.Header.Crc.Value,
|
||||
IsAvailable: true
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public override string? Key => FilePart.Header.Name;
|
||||
|
||||
public override string? LinkTarget => null;
|
||||
|
||||
36
tests/SharpCompress.Test/Rar/RarCrcExtractionTests.cs
Normal file
36
tests/SharpCompress.Test/Rar/RarCrcExtractionTests.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using SharpCompress.Archives;
|
||||
using SharpCompress.Archives.Rar;
|
||||
using SharpCompress.Common;
|
||||
using Xunit;
|
||||
|
||||
namespace SharpCompress.Test.Rar;
|
||||
|
||||
public class RarCrcExtractionTests : ArchiveTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData("Rar.rar")]
|
||||
[InlineData("Rar5.rar")]
|
||||
public void Rar_Archive_WriteToFile_Throws_On_Crc_Mismatch(string archiveName)
|
||||
{
|
||||
using var archive = RarArchive.OpenArchive(Path.Combine(TEST_ARCHIVES_PATH, archiveName));
|
||||
var entry = CorruptFirstFileCrc(archive);
|
||||
var destination = Path.Combine(SCRATCH_FILES_PATH, $"{archiveName}-crc-mismatch.txt");
|
||||
|
||||
Assert.Throws<InvalidFormatException>(() => entry.WriteToFile(destination));
|
||||
}
|
||||
|
||||
private static RarArchiveEntry CorruptFirstFileCrc(IArchive archive)
|
||||
{
|
||||
var entry = archive.Entries.OfType<RarArchiveEntry>().First(e => !e.IsDirectory);
|
||||
CorruptCrc(entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
private static void CorruptCrc(RarArchiveEntry entry)
|
||||
{
|
||||
var crc = entry.FileHeader.FileCrc.NotNull();
|
||||
crc[0] ^= 0xFF;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using SharpCompress.Archives;
|
||||
using SharpCompress.Archives.SevenZip;
|
||||
using SharpCompress.Common;
|
||||
using SharpCompress.Common.SevenZip;
|
||||
using Xunit;
|
||||
|
||||
namespace SharpCompress.Test.SevenZip;
|
||||
|
||||
public class SevenZipCrcExtractionTests : ArchiveTests
|
||||
{
|
||||
[Fact]
|
||||
public void SevenZip_Archive_WriteToFile_Throws_On_Crc_Mismatch()
|
||||
{
|
||||
using var archive = SevenZipArchive.OpenArchive(
|
||||
Path.Combine(TEST_ARCHIVES_PATH, "7Zip.LZMA.7z")
|
||||
);
|
||||
var entry = CorruptFirstFileCrc(archive);
|
||||
var destination = Path.Combine(SCRATCH_FILES_PATH, "7zip-crc-mismatch.txt");
|
||||
|
||||
var exception = Assert.Throws<InvalidFormatException>(() => entry.WriteToFile(destination));
|
||||
|
||||
Assert.Contains(entry.Key!, exception.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SevenZip_Archive_WriteToFile_Skips_Crc_Mismatch_When_Disabled()
|
||||
{
|
||||
using var archive = SevenZipArchive.OpenArchive(
|
||||
Path.Combine(TEST_ARCHIVES_PATH, "7Zip.LZMA.7z")
|
||||
);
|
||||
var entry = CorruptFirstFileCrc(archive);
|
||||
var destination = Path.Combine(SCRATCH_FILES_PATH, "7zip-crc-disabled.txt");
|
||||
|
||||
entry.WriteToFile(destination, new ExtractionOptions { CheckCrc = false });
|
||||
|
||||
Assert.True(new FileInfo(destination).Length > 0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SevenZip_Archive_WriteToFileAsync_Throws_On_Crc_Mismatch()
|
||||
{
|
||||
await using var archive = await SevenZipArchive.OpenAsyncArchive(
|
||||
Path.Combine(TEST_ARCHIVES_PATH, "7Zip.LZMA.7z")
|
||||
);
|
||||
var entries = await archive.EntriesAsync.ToListAsync();
|
||||
var entry = CorruptFirstFileCrc(entries);
|
||||
var destination = Path.Combine(SCRATCH_FILES_PATH, "7zip-crc-mismatch-async.txt");
|
||||
|
||||
var exception = await Assert.ThrowsAsync<InvalidFormatException>(async () =>
|
||||
await entry.WriteToFileAsync(destination)
|
||||
);
|
||||
|
||||
Assert.Contains(entry.Key!, exception.Message);
|
||||
}
|
||||
|
||||
private static IArchiveEntry CorruptFirstFileCrc(IArchive archive)
|
||||
{
|
||||
var entry = archive.Entries.First(e => !e.IsDirectory);
|
||||
CorruptCrc(entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
private static IArchiveEntry CorruptFirstFileCrc(
|
||||
System.Collections.Generic.IEnumerable<IArchiveEntry> entries
|
||||
)
|
||||
{
|
||||
var entry = entries.First(e => !e.IsDirectory);
|
||||
CorruptCrc(entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
private static void CorruptCrc(IArchiveEntry entry)
|
||||
{
|
||||
var sevenZipEntry = Assert.IsAssignableFrom<SevenZipEntry>(entry);
|
||||
var crc = sevenZipEntry.FilePart.Header.Crc.NotNull();
|
||||
sevenZipEntry.FilePart.Header.Crc = crc ^ 0xFFFFFFFF;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user