mirror of
https://github.com/adamhathcock/sharpcompress.git
synced 2026-11-15 17:02:03 +00:00
Fix gzip FEXTRA XLEN overflow
This commit is contained in:
committed by
Adam Hathcock
parent
bc58792b86
commit
b047d6860a
@@ -755,7 +755,7 @@ internal class ZlibBaseStream : Stream, IStreamStack
|
||||
n = _stream.Read(header.Slice(0, 2)); // 2-byte length field
|
||||
totalBytesRead += n;
|
||||
|
||||
var extraLength = (short)(header[0] + header[1] * 256);
|
||||
var extraLength = header[0] + (header[1] * 256);
|
||||
var extra = new byte[extraLength];
|
||||
n = _stream.Read(extra, 0, extra.Length);
|
||||
if (n != extraLength)
|
||||
@@ -815,7 +815,7 @@ internal class ZlibBaseStream : Stream, IStreamStack
|
||||
n = await _stream.ReadAsync(header, 0, 2, cancellationToken).ConfigureAwait(false); // 2-byte length field
|
||||
totalBytesRead += n;
|
||||
|
||||
var extraLength = (short)(header[0] + header[1] * 256);
|
||||
var extraLength = header[0] + (header[1] * 256);
|
||||
var extra = new byte[extraLength];
|
||||
n = await _stream
|
||||
.ReadAsync(extra, 0, extra.Length, cancellationToken)
|
||||
|
||||
78
tests/SharpCompress.Test/GZip/GZipExtraFieldTests.cs
Normal file
78
tests/SharpCompress.Test/GZip/GZipExtraFieldTests.cs
Normal file
@@ -0,0 +1,78 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using AwesomeAssertions;
|
||||
using SharpCompress.Test.Mocks;
|
||||
using Xunit;
|
||||
using SharpCompressionMode = SharpCompress.Compressors.CompressionMode;
|
||||
using SystemCompressionMode = System.IO.Compression.CompressionMode;
|
||||
|
||||
namespace SharpCompress.Test.GZip;
|
||||
|
||||
public class GZipExtraFieldTests
|
||||
{
|
||||
private static readonly byte[] EXPECTED_PAYLOAD = [.. "gzip payload"u8];
|
||||
|
||||
[Theory]
|
||||
[InlineData(32767)]
|
||||
[InlineData(32768)]
|
||||
[InlineData(65535)]
|
||||
public void GZipStream_Read_WithLargeExtraField_ShouldReturnPayload(int extraLength)
|
||||
{
|
||||
using var input = new MemoryStream(CreateGZipWithExtraField(extraLength));
|
||||
using var gzip = new SharpCompress.Compressors.Deflate.GZipStream(
|
||||
input,
|
||||
SharpCompressionMode.Decompress
|
||||
);
|
||||
using var output = new MemoryStream();
|
||||
|
||||
gzip.CopyTo(output);
|
||||
|
||||
_ = output.ToArray().Should().Equal(EXPECTED_PAYLOAD);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(32767)]
|
||||
[InlineData(32768)]
|
||||
[InlineData(65535)]
|
||||
public async ValueTask GZipStream_ReadAsync_WithLargeExtraField_ShouldReturnPayload(
|
||||
int extraLength
|
||||
)
|
||||
{
|
||||
using var rawInput = new MemoryStream(CreateGZipWithExtraField(extraLength));
|
||||
await using var input = new AsyncOnlyStream(rawInput, disposeStream: false);
|
||||
await using var gzip = new SharpCompress.Compressors.Deflate.GZipStream(
|
||||
input,
|
||||
SharpCompressionMode.Decompress
|
||||
);
|
||||
using var output = new MemoryStream();
|
||||
|
||||
await gzip.CopyToAsync(output);
|
||||
|
||||
_ = output.ToArray().Should().Equal(EXPECTED_PAYLOAD);
|
||||
}
|
||||
|
||||
private static byte[] CreateGZipWithExtraField(int extraLength)
|
||||
{
|
||||
using var compressed = new MemoryStream();
|
||||
using (
|
||||
var gzip = new System.IO.Compression.GZipStream(
|
||||
compressed,
|
||||
SystemCompressionMode.Compress,
|
||||
leaveOpen: true
|
||||
)
|
||||
)
|
||||
{
|
||||
gzip.Write(EXPECTED_PAYLOAD, 0, EXPECTED_PAYLOAD.Length);
|
||||
}
|
||||
|
||||
var original = compressed.ToArray();
|
||||
var result = new byte[original.Length + extraLength + 2];
|
||||
Buffer.BlockCopy(original, 0, result, 0, 10);
|
||||
result[3] |= 0x04;
|
||||
result[10] = (byte)extraLength;
|
||||
result[11] = (byte)(extraLength >> 8);
|
||||
Buffer.BlockCopy(original, 10, result, 12 + extraLength, original.Length - 10);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user