mirror of
https://github.com/adamhathcock/sharpcompress.git
synced 2026-07-09 18:47:09 +00:00
95 lines
3.5 KiB
C#
95 lines
3.5 KiB
C#
using System;
|
|
using System.Buffers.Binary;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using SharpCompress.Archives;
|
|
using SharpCompress.Archives.GZip;
|
|
using SharpCompress.Common;
|
|
using SharpCompress.Readers;
|
|
using SharpCompress.Readers.GZip;
|
|
using SharpCompress.Test.Mocks;
|
|
using Xunit;
|
|
|
|
namespace SharpCompress.Test.GZip;
|
|
|
|
public class GZipCrcExtractionTests : TestBase
|
|
{
|
|
[Fact]
|
|
public void GZipArchive_WriteToFile_Throws_On_Crc_Mismatch()
|
|
{
|
|
using var stream = new MemoryStream(ReadCorruptedGZipTrailer(corruptCrc: true));
|
|
using var archive = GZipArchive.OpenArchive(stream);
|
|
var entry = archive.Entries.Single();
|
|
var destination = Path.Combine(SCRATCH_FILES_PATH, Guid.NewGuid().ToString());
|
|
|
|
Assert.Throws<InvalidFormatException>(() => entry.WriteToFile(destination));
|
|
}
|
|
|
|
[Fact]
|
|
public void GZipArchive_WriteToFile_Throws_On_Size_Mismatch()
|
|
{
|
|
using var stream = new MemoryStream(ReadCorruptedGZipTrailer(corruptCrc: false));
|
|
using var archive = GZipArchive.OpenArchive(stream);
|
|
var entry = archive.Entries.Single();
|
|
var destination = Path.Combine(SCRATCH_FILES_PATH, Guid.NewGuid().ToString());
|
|
|
|
Assert.Throws<InvalidFormatException>(() => entry.WriteToFile(destination));
|
|
}
|
|
|
|
[Fact]
|
|
public void GZipReader_WriteEntryToFile_Throws_On_NonSeekable_Crc_Mismatch()
|
|
{
|
|
using var stream = new MemoryStream(ReadCorruptedGZipTrailer(corruptCrc: true));
|
|
using var nonSeekableStream = new ForwardOnlyStream(stream);
|
|
using var reader = GZipReader.OpenReader(nonSeekableStream);
|
|
var destination = Path.Combine(SCRATCH_FILES_PATH, Guid.NewGuid().ToString());
|
|
|
|
Assert.True(reader.MoveToNextEntry());
|
|
Assert.Throws<InvalidFormatException>(() => reader.WriteEntryToFile(destination));
|
|
}
|
|
|
|
[Fact]
|
|
public void GZipArchive_WriteToFile_Skips_Trailer_Validation_When_CheckCrc_Is_False()
|
|
{
|
|
using var stream = new MemoryStream(ReadCorruptedGZipTrailer(corruptCrc: true));
|
|
using var archive = GZipArchive.OpenArchive(stream);
|
|
var entry = archive.Entries.Single();
|
|
var destination = Path.Combine(SCRATCH_FILES_PATH, Guid.NewGuid().ToString());
|
|
|
|
entry.WriteToFile(destination, new ExtractionOptions { CheckCrc = false });
|
|
|
|
Assert.Equal(
|
|
new FileInfo(Path.Combine(TEST_ARCHIVES_PATH, "Tar.tar")).Length,
|
|
new FileInfo(destination).Length
|
|
);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GZipArchive_WriteToFileAsync_Throws_On_Crc_Mismatch()
|
|
{
|
|
#if LEGACY_DOTNET
|
|
using var stream = new MemoryStream(ReadCorruptedGZipTrailer(corruptCrc: true));
|
|
#else
|
|
await using var stream = new MemoryStream(ReadCorruptedGZipTrailer(corruptCrc: true));
|
|
#endif
|
|
await using var archive = await GZipArchive.OpenAsyncArchive(stream);
|
|
var entry = await archive.EntriesAsync.SingleAsync();
|
|
var destination = Path.Combine(SCRATCH_FILES_PATH, Guid.NewGuid().ToString());
|
|
|
|
await Assert.ThrowsAsync<InvalidFormatException>(async () =>
|
|
await entry.WriteToFileAsync(destination)
|
|
);
|
|
}
|
|
|
|
private static byte[] ReadCorruptedGZipTrailer(bool corruptCrc)
|
|
{
|
|
var bytes = File.ReadAllBytes(Path.Combine(TEST_ARCHIVES_PATH, "Tar.tar.gz"));
|
|
var trailer = bytes.AsSpan(bytes.Length - 8);
|
|
var offset = corruptCrc ? 0 : 4;
|
|
var value = BinaryPrimitives.ReadUInt32LittleEndian(trailer[offset..]);
|
|
BinaryPrimitives.WriteUInt32LittleEndian(trailer[offset..], value + 1);
|
|
return bytes;
|
|
}
|
|
}
|