mirror of
https://github.com/adamhathcock/sharpcompress.git
synced 2026-09-25 00:15:15 +00:00
not sure I like this fix
This commit is contained in:
@@ -48,11 +48,17 @@ public partial class EntryStream : Stream
|
||||
//Need a safe standard approach to this - it's okay for compression to overreads. Handling needs to be standardised
|
||||
if (_stream is IStreamStack ss)
|
||||
{
|
||||
if (ss.BaseStream() is SharpCompress.Compressors.Deflate.DeflateStream deflateStream)
|
||||
if (
|
||||
ss.GetStream<SharpCompress.Compressors.Deflate.DeflateStream>()
|
||||
is SharpCompress.Compressors.Deflate.DeflateStream deflateStream
|
||||
)
|
||||
{
|
||||
deflateStream.Flush(); //Deflate over reads. Knock it back
|
||||
}
|
||||
else if (ss.BaseStream() is SharpCompress.Compressors.LZMA.LzmaStream lzmaStream)
|
||||
else if (
|
||||
ss.GetStream<SharpCompress.Compressors.LZMA.LzmaStream>()
|
||||
is SharpCompress.Compressors.LZMA.LzmaStream lzmaStream
|
||||
)
|
||||
{
|
||||
lzmaStream.Flush(); //Lzma over reads. Knock it back
|
||||
}
|
||||
|
||||
@@ -29,10 +29,11 @@ using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using SharpCompress.IO;
|
||||
|
||||
namespace SharpCompress.Compressors.Deflate;
|
||||
|
||||
public partial class DeflateStream : Stream
|
||||
public partial class DeflateStream : Stream, IStreamStack
|
||||
{
|
||||
private readonly ZlibBaseStream _baseStream;
|
||||
private bool _disposed;
|
||||
@@ -269,6 +270,8 @@ public partial class DeflateStream : Stream
|
||||
}
|
||||
}
|
||||
|
||||
Stream IStreamStack.BaseStream() => _baseStream;
|
||||
|
||||
/// <summary>
|
||||
/// Flush the stream.
|
||||
/// </summary>
|
||||
|
||||
@@ -34,6 +34,7 @@ using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using SharpCompress.Common.Tar.Headers;
|
||||
using SharpCompress.IO;
|
||||
|
||||
namespace SharpCompress.Compressors.Deflate;
|
||||
|
||||
@@ -44,8 +45,10 @@ internal enum ZlibStreamFlavor
|
||||
GZIP = 1952,
|
||||
}
|
||||
|
||||
internal class ZlibBaseStream : Stream
|
||||
internal class ZlibBaseStream : Stream, IStreamStack
|
||||
{
|
||||
Stream IStreamStack.BaseStream() => _stream;
|
||||
|
||||
protected internal ZlibCodec _z; // deferred init... new ZlibCodec();
|
||||
|
||||
protected internal StreamMode _streamMode = StreamMode.Undefined;
|
||||
@@ -590,8 +593,24 @@ internal class ZlibBaseStream : Stream
|
||||
{
|
||||
_stream.Flush();
|
||||
}
|
||||
//rewind the buffer
|
||||
//unused: ((IStreamStack)this).Rewind(z.AvailableBytesIn);
|
||||
else if (_streamMode == StreamMode.Reader && z.AvailableBytesIn > 0)
|
||||
{
|
||||
// Rewind the underlying stream by the number of unconsumed bytes in the buffer
|
||||
// This handles the case where the decompressor over-read past the end of the entry
|
||||
if (_stream is IStreamStack stack)
|
||||
{
|
||||
var root = stack.GetRootStream();
|
||||
if (root.CanSeek)
|
||||
{
|
||||
// Try to seek backward on the root stream; ignore if not supported
|
||||
try
|
||||
{
|
||||
root.Seek(-z.AvailableBytesIn, SeekOrigin.Current);
|
||||
}
|
||||
catch (NotSupportedException) { }
|
||||
}
|
||||
}
|
||||
}
|
||||
z.AvailableBytesIn = 0;
|
||||
}
|
||||
|
||||
@@ -604,8 +623,24 @@ internal class ZlibBaseStream : Stream
|
||||
{
|
||||
await _stream.FlushAsync(cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
//rewind the buffer
|
||||
//unused: ((IStreamStack)this).Rewind(z.AvailableBytesIn);
|
||||
else if (_streamMode == StreamMode.Reader && z.AvailableBytesIn > 0)
|
||||
{
|
||||
// Rewind the underlying stream by the number of unconsumed bytes in the buffer
|
||||
// This handles the case where the decompressor over-read past the end of the entry
|
||||
if (_stream is IStreamStack stack)
|
||||
{
|
||||
var root = stack.GetRootStream();
|
||||
if (root.CanSeek)
|
||||
{
|
||||
// Try to seek backward on the root stream; ignore if not supported
|
||||
try
|
||||
{
|
||||
root.Seek(-z.AvailableBytesIn, SeekOrigin.Current);
|
||||
}
|
||||
catch (NotSupportedException) { }
|
||||
}
|
||||
}
|
||||
}
|
||||
z.AvailableBytesIn = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,10 +4,11 @@ using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using SharpCompress.Compressors.LZMA.LZ;
|
||||
using SharpCompress.IO;
|
||||
|
||||
namespace SharpCompress.Compressors.LZMA;
|
||||
|
||||
public partial class LzmaStream : Stream
|
||||
public partial class LzmaStream : Stream, IStreamStack
|
||||
{
|
||||
private readonly Stream? _inputStream;
|
||||
private readonly long _inputSize;
|
||||
@@ -190,6 +191,8 @@ public partial class LzmaStream : Stream
|
||||
|
||||
public override void Flush() { }
|
||||
|
||||
Stream IStreamStack.BaseStream() => _inputStream!;
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (_isDisposed)
|
||||
|
||||
@@ -15,4 +15,39 @@ namespace SharpCompress.IO
|
||||
/// </summary>
|
||||
Stream BaseStream();
|
||||
}
|
||||
|
||||
public static class StreamStackExtensions
|
||||
{
|
||||
public static T? GetStream<T>(this IStreamStack stack)
|
||||
where T : Stream
|
||||
{
|
||||
var baseStream = stack.BaseStream();
|
||||
if (baseStream is T tStream)
|
||||
{
|
||||
return tStream;
|
||||
}
|
||||
else if (baseStream is IStreamStack innerStack)
|
||||
{
|
||||
return innerStack.GetStream<T>();
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the root underlying stream at the bottom of the stack.
|
||||
/// This is useful for seeking when the intermediate streams don't support it.
|
||||
/// </summary>
|
||||
public static Stream GetRootStream(this IStreamStack stack)
|
||||
{
|
||||
var current = stack.BaseStream();
|
||||
while (current is IStreamStack streamStack)
|
||||
{
|
||||
current = streamStack.BaseStream();
|
||||
}
|
||||
return current;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,20 +105,22 @@ internal partial class RewindableStream : Stream
|
||||
}
|
||||
return streamPosition;
|
||||
}
|
||||
set
|
||||
{
|
||||
long bufferStart = streamPosition - bufferStream.Length;
|
||||
long bufferEnd = streamPosition;
|
||||
set => SeekToPosition(value);
|
||||
}
|
||||
|
||||
if (value >= bufferStart && value < bufferEnd)
|
||||
{
|
||||
isRewound = true;
|
||||
bufferStream.Position = value - bufferStart;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotSupportedException("Cannot seek outside buffered region.");
|
||||
}
|
||||
private void SeekToPosition(long targetPosition)
|
||||
{
|
||||
long bufferStart = streamPosition - bufferStream.Length;
|
||||
long bufferEnd = streamPosition;
|
||||
|
||||
if (targetPosition >= bufferStart && targetPosition <= bufferEnd)
|
||||
{
|
||||
isRewound = true;
|
||||
bufferStream.Position = targetPosition - bufferStart;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotSupportedException("Cannot seek outside buffered region.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,7 +161,19 @@ internal partial class RewindableStream : Stream
|
||||
return read;
|
||||
}
|
||||
|
||||
public override long Seek(long offset, SeekOrigin origin) => throw new NotSupportedException();
|
||||
public override long Seek(long offset, SeekOrigin origin)
|
||||
{
|
||||
long targetPosition = origin switch
|
||||
{
|
||||
SeekOrigin.Begin => offset,
|
||||
SeekOrigin.Current => Position + offset,
|
||||
SeekOrigin.End => throw new NotSupportedException("Seeking from end is not supported."),
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(origin)),
|
||||
};
|
||||
|
||||
SeekToPosition(targetPosition);
|
||||
return targetPosition;
|
||||
}
|
||||
|
||||
public override void SetLength(long value) => throw new NotSupportedException();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user