Merge pull request #878 from Morilli/fix-xzblock-padding

Fix XZBlock padding calculation when its stream's starting position % 4 != 0
This commit is contained in:
Adam Hathcock
2024-12-20 08:50:46 +00:00
committed by GitHub
3 changed files with 19 additions and 4 deletions

View File

@@ -25,13 +25,14 @@ public sealed class XZBlock : XZReadOnlyStream
private bool _endOfStream;
private bool _paddingSkipped;
private bool _crcChecked;
private ulong _bytesRead;
private readonly long _startPosition;
public XZBlock(Stream stream, CheckType checkType, int checkSize)
: base(stream)
{
_checkType = checkType;
_checkSize = checkSize;
_startPosition = stream.Position;
}
public override int Read(byte[] buffer, int offset, int count)
@@ -67,13 +68,12 @@ public sealed class XZBlock : XZReadOnlyStream
CheckCrc();
}
_bytesRead += (ulong)bytesRead;
return bytesRead;
}
private void SkipPadding()
{
var bytes = (int)(BaseStream.Position % 4);
var bytes = (BaseStream.Position - _startPosition) % 4;
if (bytes > 0)
{
var paddingBytes = new byte[4 - bytes];

View File

@@ -31,7 +31,7 @@ public class ForwardOnlyStream(Stream stream) : Stream
public override long Position
{
get => throw new NotSupportedException();
get => stream.Position;
set => throw new NotSupportedException();
}

View File

@@ -93,4 +93,19 @@ public class XzBlockTests : XzTestsBase
sr.ReadToEnd();
Assert.Equal(0L, CompressedIndexedStream.Position % 4L);
}
[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.
var xzBlock = new XZBlock(compressedUnalignedStream, CheckType.CRC64, 8);
var sr = new StreamReader(xzBlock);
sr.ReadToEnd();
Assert.Equal(1L, compressedUnalignedStream.Position % 4L);
}
}