Skip to content

Commit

Permalink
Merge pull request #878 from Morilli/fix-xzblock-padding
Browse files Browse the repository at this point in the history
Fix XZBlock padding calculation when its stream's starting position % 4 != 0
  • Loading branch information
adamhathcock authored Dec 20, 2024
2 parents 7f79c49 + 10cc270 commit 5842da8
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 4 deletions.
6 changes: 3 additions & 3 deletions src/SharpCompress/Compressors/Xz/XZBlock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -67,13 +68,12 @@ public override int Read(byte[] buffer, int offset, int count)
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];
Expand Down
2 changes: 1 addition & 1 deletion tests/SharpCompress.Test/Mocks/ForwardOnlyStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public override void Flush() { }

public override long Position
{
get => throw new NotSupportedException();
get => stream.Position;
set => throw new NotSupportedException();
}

Expand Down
15 changes: 15 additions & 0 deletions tests/SharpCompress.Test/Xz/XZBlockTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,4 +93,19 @@ public void SkipsPaddingWhenPresent()
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);
}
}

0 comments on commit 5842da8

Please sign in to comment.