mirror of
https://github.com/adamhathcock/sharpcompress.git
synced 2026-09-22 15:04:43 +00:00
clean up shrink stream to ensure correctness
This commit is contained in:
@@ -2,7 +2,6 @@ using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using SharpCompress.Common;
|
||||
|
||||
namespace SharpCompress.Compressors.Shrink;
|
||||
|
||||
@@ -16,12 +15,7 @@ internal partial class ShrinkStream : Stream
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
var shrinkStream = new ShrinkStream(
|
||||
stream,
|
||||
compressionMode,
|
||||
compressedSize,
|
||||
uncompressedSize
|
||||
);
|
||||
var shrinkStream = new ShrinkStream(stream, uncompressedSize);
|
||||
await shrinkStream.DecompressAsync(cancellationToken).ConfigureAwait(false);
|
||||
return shrinkStream;
|
||||
}
|
||||
@@ -33,26 +27,16 @@ internal partial class ShrinkStream : Stream
|
||||
return;
|
||||
}
|
||||
|
||||
// Read actual compressed data from stream rather than pre-allocating based on the
|
||||
// Read actual compressed data from the stream rather than pre-allocating based on the
|
||||
// declared compressed size, which may be crafted to cause an OutOfMemoryException.
|
||||
// The stream is already bounded by ReadOnlySubStream in ZipFilePart.
|
||||
using var srcMs = new MemoryStream();
|
||||
await inStream.CopyToAsync(srcMs, 81920, cancellationToken).ConfigureAwait(false);
|
||||
await _inStream.CopyToAsync(srcMs, 81920, cancellationToken).ConfigureAwait(false);
|
||||
var src = srcMs.ToArray();
|
||||
var srcLen = src.Length;
|
||||
|
||||
// Decompress synchronously (CPU-bound operation)
|
||||
var srcUsed = 0;
|
||||
var dstUsed = 0;
|
||||
|
||||
HwUnshrink.Unshrink(
|
||||
src,
|
||||
srcLen,
|
||||
out srcUsed,
|
||||
_byteOut,
|
||||
(int)_uncompressedSize,
|
||||
out dstUsed
|
||||
);
|
||||
HwUnshrink.Unshrink(src, srcLen, out _, _byteOut, (int)_uncompressedSize, out var dstUsed);
|
||||
_outBytesCount = dstUsed;
|
||||
_decompressed = true;
|
||||
}
|
||||
|
||||
@@ -5,33 +5,23 @@ namespace SharpCompress.Compressors.Shrink;
|
||||
|
||||
internal partial class ShrinkStream : Stream
|
||||
{
|
||||
private Stream inStream;
|
||||
private readonly Stream _inStream;
|
||||
|
||||
private long _uncompressedSize;
|
||||
private byte[] _byteOut;
|
||||
private readonly long _uncompressedSize;
|
||||
private readonly byte[] _byteOut;
|
||||
private long _outBytesCount;
|
||||
private bool _decompressed;
|
||||
private long _position;
|
||||
|
||||
public ShrinkStream(
|
||||
Stream stream,
|
||||
CompressionMode compressionMode,
|
||||
long compressedSize,
|
||||
long uncompressedSize
|
||||
)
|
||||
public ShrinkStream(Stream stream, long uncompressedSize)
|
||||
{
|
||||
inStream = stream;
|
||||
_inStream = stream;
|
||||
|
||||
_uncompressedSize = uncompressedSize;
|
||||
_byteOut = new byte[_uncompressedSize];
|
||||
_outBytesCount = 0L;
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
public override bool CanRead => true;
|
||||
|
||||
public override bool CanSeek => true;
|
||||
@@ -52,23 +42,21 @@ internal partial class ShrinkStream : Stream
|
||||
{
|
||||
if (!_decompressed)
|
||||
{
|
||||
// Read actual compressed data from stream rather than pre-allocating based on the
|
||||
// Read actual compressed data from the stream rather than pre-allocating based on the
|
||||
// declared compressed size, which may be crafted to cause an OutOfMemoryException.
|
||||
// The stream is already bounded by ReadOnlySubStream in ZipFilePart.
|
||||
using var srcMs = new MemoryStream();
|
||||
inStream.CopyTo(srcMs);
|
||||
_inStream.CopyTo(srcMs);
|
||||
var src = srcMs.ToArray();
|
||||
var srcLen = src.Length;
|
||||
var srcUsed = 0;
|
||||
var dstUsed = 0;
|
||||
|
||||
HwUnshrink.Unshrink(
|
||||
src,
|
||||
srcLen,
|
||||
out srcUsed,
|
||||
out _,
|
||||
_byteOut,
|
||||
(int)_uncompressedSize,
|
||||
out dstUsed
|
||||
out var dstUsed
|
||||
);
|
||||
_outBytesCount = dstUsed;
|
||||
_decompressed = true;
|
||||
|
||||
@@ -27,12 +27,7 @@ public sealed class ShrinkCompressionProvider : ContextRequiredDecompressionProv
|
||||
{
|
||||
ValidateRequiredSizes(context, "Shrink");
|
||||
|
||||
return new ShrinkStream(
|
||||
source,
|
||||
CompressionMode.Decompress,
|
||||
context.InputSize,
|
||||
context.OutputSize
|
||||
);
|
||||
return new ShrinkStream(source, context.OutputSize);
|
||||
}
|
||||
|
||||
public override async ValueTask<Stream> CreateDecompressStreamAsync(
|
||||
|
||||
Reference in New Issue
Block a user