2017-06-11 13:44:01 +01:00
|
|
|
using System.IO;
|
2022-12-20 15:06:44 +00:00
|
|
|
using System.Text;
|
2024-04-23 14:48:33 +01:00
|
|
|
using SharpCompress.Common;
|
2017-06-11 13:44:01 +01:00
|
|
|
using SharpCompress.Compressors.Xz;
|
|
|
|
|
using Xunit;
|
|
|
|
|
|
2022-12-20 15:06:44 +00:00
|
|
|
namespace SharpCompress.Test.Xz;
|
|
|
|
|
|
2024-03-14 08:53:08 +00:00
|
|
|
public class XzBlockTests : XzTestsBase
|
2017-06-11 13:44:01 +01:00
|
|
|
{
|
2022-12-20 15:20:49 +00:00
|
|
|
protected override void Rewind(Stream stream) => stream.Position = 12;
|
2017-06-11 13:44:01 +01:00
|
|
|
|
2022-12-20 15:20:49 +00:00
|
|
|
protected override void RewindIndexed(Stream stream) => stream.Position = 12;
|
2017-09-17 23:14:23 +02:00
|
|
|
|
2022-12-20 15:06:44 +00:00
|
|
|
private byte[] ReadBytes(XZBlock block, int bytesToRead)
|
|
|
|
|
{
|
|
|
|
|
var buffer = new byte[bytesToRead];
|
|
|
|
|
var read = block.Read(buffer, 0, bytesToRead);
|
|
|
|
|
if (read != bytesToRead)
|
2017-06-11 13:44:01 +01:00
|
|
|
{
|
2022-12-20 15:06:44 +00:00
|
|
|
throw new EndOfStreamException();
|
2017-06-11 13:44:01 +01:00
|
|
|
}
|
|
|
|
|
|
2022-12-20 15:06:44 +00:00
|
|
|
return buffer;
|
|
|
|
|
}
|
2017-06-11 13:44:01 +01:00
|
|
|
|
2022-12-20 15:06:44 +00:00
|
|
|
[Fact]
|
|
|
|
|
public void OnFindIndexBlockThrow()
|
|
|
|
|
{
|
|
|
|
|
var bytes = new byte[] { 0 };
|
|
|
|
|
using Stream indexBlockStream = new MemoryStream(bytes);
|
2026-02-13 14:26:54 +00:00
|
|
|
using var xzBlock = new XZBlock(indexBlockStream, CheckType.CRC64, 8);
|
2022-12-20 15:06:44 +00:00
|
|
|
Assert.Throws<XZIndexMarkerReachedException>(() =>
|
2017-06-11 13:44:01 +01:00
|
|
|
{
|
2024-03-14 08:53:08 +00:00
|
|
|
ReadBytes(xzBlock, 1);
|
2022-12-20 15:06:44 +00:00
|
|
|
});
|
|
|
|
|
}
|
2017-06-11 13:44:01 +01:00
|
|
|
|
2022-12-20 15:06:44 +00:00
|
|
|
[Fact]
|
|
|
|
|
public void CrcIncorrectThrows()
|
|
|
|
|
{
|
|
|
|
|
var bytes = (byte[])Compressed.Clone();
|
|
|
|
|
bytes[20]++;
|
|
|
|
|
using Stream badCrcStream = new MemoryStream(bytes);
|
|
|
|
|
Rewind(badCrcStream);
|
2026-02-13 14:26:54 +00:00
|
|
|
using var xzBlock = new XZBlock(badCrcStream, CheckType.CRC64, 8);
|
2024-04-23 14:47:40 +01:00
|
|
|
var ex = Assert.Throws<InvalidFormatException>(() =>
|
2017-06-11 13:44:01 +01:00
|
|
|
{
|
2024-03-14 08:53:08 +00:00
|
|
|
ReadBytes(xzBlock, 1);
|
2022-12-20 15:06:44 +00:00
|
|
|
});
|
|
|
|
|
Assert.Equal("Block header corrupt", ex.Message);
|
|
|
|
|
}
|
2017-06-11 13:44:01 +01:00
|
|
|
|
2022-12-20 15:06:44 +00:00
|
|
|
[Fact]
|
|
|
|
|
public void CanReadM()
|
|
|
|
|
{
|
2026-02-13 14:26:54 +00:00
|
|
|
using var xzBlock = new XZBlock(CompressedStream, CheckType.CRC64, 8);
|
2024-03-14 08:53:08 +00:00
|
|
|
Assert.Equal(Encoding.ASCII.GetBytes("M"), ReadBytes(xzBlock, 1));
|
2022-12-20 15:06:44 +00:00
|
|
|
}
|
2017-06-11 13:44:01 +01:00
|
|
|
|
2022-12-20 15:06:44 +00:00
|
|
|
[Fact]
|
|
|
|
|
public void CanReadMary()
|
|
|
|
|
{
|
2026-02-13 14:26:54 +00:00
|
|
|
using var xzBlock = new XZBlock(CompressedStream, CheckType.CRC64, 8);
|
2024-03-14 08:53:08 +00:00
|
|
|
Assert.Equal(Encoding.ASCII.GetBytes("M"), ReadBytes(xzBlock, 1));
|
|
|
|
|
Assert.Equal(Encoding.ASCII.GetBytes("a"), ReadBytes(xzBlock, 1));
|
|
|
|
|
Assert.Equal(Encoding.ASCII.GetBytes("ry"), ReadBytes(xzBlock, 2));
|
2022-12-20 15:06:44 +00:00
|
|
|
}
|
2017-09-17 23:14:23 +02:00
|
|
|
|
2022-12-20 15:06:44 +00:00
|
|
|
[Fact]
|
|
|
|
|
public void CanReadPoemWithStreamReader()
|
|
|
|
|
{
|
2024-03-14 08:53:08 +00:00
|
|
|
var xzBlock = new XZBlock(CompressedStream, CheckType.CRC64, 8);
|
2026-02-13 14:26:54 +00:00
|
|
|
using var sr = new StreamReader(xzBlock);
|
2026-06-13 14:31:36 +01:00
|
|
|
Assert.Equal(Original, sr.ReadToEnd());
|
2022-12-20 15:06:44 +00:00
|
|
|
}
|
2017-09-17 23:14:23 +02:00
|
|
|
|
2022-12-20 15:06:44 +00:00
|
|
|
[Fact]
|
|
|
|
|
public void NoopWhenNoPadding()
|
|
|
|
|
{
|
|
|
|
|
// CompressedStream's only block has no padding.
|
2026-02-13 14:26:54 +00:00
|
|
|
using var xzBlock = new XZBlock(CompressedStream, CheckType.CRC64, 8);
|
|
|
|
|
using var sr = new StreamReader(xzBlock);
|
2022-12-20 15:06:44 +00:00
|
|
|
sr.ReadToEnd();
|
|
|
|
|
Assert.Equal(0L, CompressedStream.Position % 4L);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Fact]
|
|
|
|
|
public void SkipsPaddingWhenPresent()
|
|
|
|
|
{
|
2026-06-13 14:31:36 +01:00
|
|
|
// CompressedIndexedStream uses CRC32 checks.
|
|
|
|
|
using var xzBlock = new XZBlock(CompressedIndexedStream, CheckType.CRC32, 4);
|
2026-02-13 14:26:54 +00:00
|
|
|
using var sr = new StreamReader(xzBlock);
|
2022-12-20 15:06:44 +00:00
|
|
|
sr.ReadToEnd();
|
|
|
|
|
Assert.Equal(0L, CompressedIndexedStream.Position % 4L);
|
2017-06-11 13:44:01 +01:00
|
|
|
}
|
2024-10-29 02:55:43 +01:00
|
|
|
|
|
|
|
|
[Fact]
|
|
|
|
|
public void HandlesPaddingInUnalignedBlock()
|
|
|
|
|
{
|
|
|
|
|
var compressedUnaligned = new byte[Compressed.Length + 1];
|
|
|
|
|
Compressed.CopyTo(compressedUnaligned, 1);
|
|
|
|
|
var compressedUnalignedStream = new MemoryStream(compressedUnaligned);
|
|
|
|
|
compressedUnalignedStream.Position = 13;
|
|
|
|
|
|
|
|
|
|
// Compressed's only block has no padding.
|
2026-02-13 14:26:54 +00:00
|
|
|
using var xzBlock = new XZBlock(compressedUnalignedStream, CheckType.CRC64, 8);
|
|
|
|
|
using var sr = new StreamReader(xzBlock);
|
2024-10-29 02:55:43 +01:00
|
|
|
sr.ReadToEnd();
|
|
|
|
|
Assert.Equal(1L, compressedUnalignedStream.Position % 4L);
|
|
|
|
|
}
|
2017-06-11 13:44:01 +01:00
|
|
|
}
|