Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions src/SharpCompress/Archives/ArchiveFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Linq;
using SharpCompress.Common;
using SharpCompress.Factories;
using SharpCompress.IO;
using SharpCompress.Readers;

namespace SharpCompress.Archives;
Expand All @@ -19,7 +20,7 @@ public static class ArchiveFactory
public static IArchive Open(Stream stream, ReaderOptions? readerOptions = null)
{
readerOptions ??= new ReaderOptions();

stream = new SharpCompressStream(stream, bufferSize: readerOptions.BufferSize);
return FindFactory<IArchiveFactory>(stream).Open(stream, readerOptions);
}

Expand Down Expand Up @@ -165,14 +166,22 @@ private static T FindFactory<T>(Stream stream)
);
}

public static bool IsArchive(string filePath, out ArchiveType? type)
public static bool IsArchive(
string filePath,
out ArchiveType? type,
int bufferSize = ReaderOptions.DefaultBufferSize
)
{
filePath.CheckNotNullOrEmpty(nameof(filePath));
using Stream s = File.OpenRead(filePath);
return IsArchive(s, out type);
return IsArchive(s, out type, bufferSize);
}

public static bool IsArchive(Stream stream, out ArchiveType? type)
public static bool IsArchive(
Stream stream,
out ArchiveType? type,
int bufferSize = ReaderOptions.DefaultBufferSize
)
{
type = null;
stream.CheckNotNull(nameof(stream));
Expand Down
9 changes: 6 additions & 3 deletions src/SharpCompress/Archives/AutoArchiveFactory.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.IO;
using SharpCompress.Common;
Expand All @@ -14,8 +14,11 @@ class AutoArchiveFactory : IArchiveFactory

public IEnumerable<string> GetSupportedExtensions() => throw new NotSupportedException();

public bool IsArchive(Stream stream, string? password = null) =>
throw new NotSupportedException();
public bool IsArchive(
Stream stream,
string? password = null,
int bufferSize = ReaderOptions.DefaultBufferSize
) => throw new NotSupportedException();

public FileInfo? GetFilePart(int index, FileInfo part1) => throw new NotSupportedException();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public override Stream OpenEntryStream()
{
//ensure new stream is at the start, this could be reset
stream.Seek(0, SeekOrigin.Begin);
return NonDisposingStream.Create(stream);
return SharpCompressStream.Create(stream, leaveOpen: true);
}

internal override void Close()
Expand Down
2 changes: 1 addition & 1 deletion src/SharpCompress/Archives/Tar/TarWritableArchiveEntry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public override Stream OpenEntryStream()
{
//ensure new stream is at the start, this could be reset
stream.Seek(0, SeekOrigin.Begin);
return NonDisposingStream.Create(stream);
return SharpCompressStream.Create(stream, leaveOpen: true);
}

internal override void Close()
Expand Down
39 changes: 32 additions & 7 deletions src/SharpCompress/Archives/Zip/ZipArchive.cs
Original file line number Diff line number Diff line change
Expand Up @@ -122,24 +122,40 @@ public static ZipArchive Open(Stream stream, ReaderOptions? readerOptions = null
);
}

public static bool IsZipFile(string filePath, string? password = null) =>
IsZipFile(new FileInfo(filePath), password);
public static bool IsZipFile(
string filePath,
string? password = null,
int bufferSize = ReaderOptions.DefaultBufferSize
) => IsZipFile(new FileInfo(filePath), password, bufferSize);

public static bool IsZipFile(FileInfo fileInfo, string? password = null)
public static bool IsZipFile(
FileInfo fileInfo,
string? password = null,
int bufferSize = ReaderOptions.DefaultBufferSize
)
{
if (!fileInfo.Exists)
{
return false;
}
using Stream stream = fileInfo.OpenRead();
return IsZipFile(stream, password);
return IsZipFile(stream, password, bufferSize);
}

public static bool IsZipFile(Stream stream, string? password = null)
public static bool IsZipFile(
Stream stream,
string? password = null,
int bufferSize = ReaderOptions.DefaultBufferSize
)
{
var headerFactory = new StreamingZipHeaderFactory(password, new ArchiveEncoding(), null);
try
{
if (stream is not SharpCompressStream)
{
stream = new SharpCompressStream(stream, bufferSize: bufferSize);
}

var header = headerFactory
.ReadStreamHeader(stream)
.FirstOrDefault(x => x.ZipHeaderType != ZipHeaderType.Split);
Expand All @@ -159,11 +175,20 @@ public static bool IsZipFile(Stream stream, string? password = null)
}
}

public static bool IsZipMulti(Stream stream, string? password = null)
public static bool IsZipMulti(
Stream stream,
string? password = null,
int bufferSize = ReaderOptions.DefaultBufferSize
)
{
var headerFactory = new StreamingZipHeaderFactory(password, new ArchiveEncoding(), null);
try
{
if (stream is not SharpCompressStream)
{
stream = new SharpCompressStream(stream, bufferSize: bufferSize);
}

var header = headerFactory
.ReadStreamHeader(stream)
.FirstOrDefault(x => x.ZipHeaderType != ZipHeaderType.Split);
Expand Down Expand Up @@ -202,7 +227,7 @@ protected override IEnumerable<ZipVolume> LoadVolumes(SourceStream stream)
if (streams.Count() > 1) //test part 2 - true = multipart not split
{
streams[1].Position += 4; //skip the POST_DATA_DESCRIPTOR to prevent an exception
var isZip = IsZipFile(streams[1], ReaderOptions.Password);
var isZip = IsZipFile(streams[1], ReaderOptions.Password, ReaderOptions.BufferSize);
streams[1].Position -= 4;
if (isZip)
{
Expand Down
2 changes: 1 addition & 1 deletion src/SharpCompress/Archives/Zip/ZipWritableArchiveEntry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public override Stream OpenEntryStream()
{
//ensure new stream is at the start, this could be reset
stream.Seek(0, SeekOrigin.Begin);
return NonDisposingStream.Create(stream);
return SharpCompressStream.Create(stream, leaveOpen: true);
}

internal override void Close()
Expand Down
46 changes: 44 additions & 2 deletions src/SharpCompress/Common/EntryStream.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,33 @@
using System;
using System.IO;
using System.IO.Compression;
using SharpCompress.IO;
using SharpCompress.Readers;

namespace SharpCompress.Common;

public class EntryStream : Stream
public class EntryStream : Stream, IStreamStack
{
#if DEBUG_STREAMS
long IStreamStack.InstanceId { get; set; }
#endif
int IStreamStack.DefaultBufferSize { get; set; }

Stream IStreamStack.BaseStream() => _stream;

int IStreamStack.BufferSize
{
get => 0;
set { }
}
int IStreamStack.BufferPosition
{
get => 0;
set { }
}

void IStreamStack.SetPosition(long position) { }

private readonly IReader _reader;
private readonly Stream _stream;
private bool _completed;
Expand All @@ -15,6 +37,9 @@ internal EntryStream(IReader reader, Stream stream)
{
_reader = reader;
_stream = stream;
#if DEBUG_STREAMS
this.DebugConstruct(typeof(EntryStream));
#endif
}

/// <summary>
Expand All @@ -32,11 +57,28 @@ protected override void Dispose(bool disposing)
{
SkipEntry();
}

//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)
{
deflateStream.Flush(); //Deflate over reads. Knock it back
}
else if (ss.BaseStream() is SharpCompress.Compressors.LZMA.LzmaStream lzmaStream)
{
lzmaStream.Flush(); //Lzma over reads. Knock it back
}
}

if (_isDisposed)
{
return;
}
_isDisposed = true;
#if DEBUG_STREAMS
this.DebugDispose(typeof(EntryStream));
#endif
base.Dispose(disposing);
_stream.Dispose();
}
Expand All @@ -53,7 +95,7 @@ public override void Flush() { }

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

Expand Down
33 changes: 30 additions & 3 deletions src/SharpCompress/Common/Tar/TarReadOnlySubStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,38 @@

namespace SharpCompress.Common.Tar;

internal class TarReadOnlySubStream : NonDisposingStream
internal class TarReadOnlySubStream : SharpCompressStream, IStreamStack
{
#if DEBUG_STREAMS
long IStreamStack.InstanceId { get; set; }
#endif

Stream IStreamStack.BaseStream() => base.Stream;

int IStreamStack.BufferSize
{
get => 0;
set { }
}
int IStreamStack.BufferPosition
{
get => 0;
set { }
}

void IStreamStack.SetPosition(long position) { }

private bool _isDisposed;
private long _amountRead;

public TarReadOnlySubStream(Stream stream, long bytesToRead)
: base(stream, throwOnDispose: false) => BytesLeftToRead = bytesToRead;
: base(stream, leaveOpen: true, throwOnDispose: false)
{
BytesLeftToRead = bytesToRead;
#if DEBUG_STREAMS
this.DebugConstruct(typeof(TarReadOnlySubStream));
#endif
}

protected override void Dispose(bool disposing)
{
Expand All @@ -20,7 +45,9 @@ protected override void Dispose(bool disposing)
}

_isDisposed = true;

#if DEBUG_STREAMS
this.DebugDispose(typeof(TarReadOnlySubStream));
#endif
if (disposing)
{
// Ensure we read all remaining blocks for this entry.
Expand Down
6 changes: 5 additions & 1 deletion src/SharpCompress/Common/Volume.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,12 @@ internal Volume(Stream stream, ReaderOptions? readerOptions, int index = 0)
_baseStream = stream;
if (ReaderOptions.LeaveStreamOpen)
{
stream = NonDisposingStream.Create(stream);
stream = SharpCompressStream.Create(stream, leaveOpen: true);
}

if (stream is IStreamStack ss)
ss.SetBuffer(ReaderOptions.BufferSize, true);

_actualStream = stream;
}

Expand Down
30 changes: 29 additions & 1 deletion src/SharpCompress/Common/Zip/PkwareTraditionalCryptoStream.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.IO;
using SharpCompress.IO;

namespace SharpCompress.Common.Zip;

Expand All @@ -9,8 +10,28 @@ internal enum CryptoMode
Decrypt,
}

internal class PkwareTraditionalCryptoStream : Stream
internal class PkwareTraditionalCryptoStream : Stream, IStreamStack
{
#if DEBUG_STREAMS
long IStreamStack.InstanceId { get; set; }
#endif
int IStreamStack.DefaultBufferSize { get; set; }

Stream IStreamStack.BaseStream() => _stream;

int IStreamStack.BufferSize
{
get => 0;
set { return; }
}
int IStreamStack.BufferPosition
{
get => 0;
set { return; }
}

void IStreamStack.SetPosition(long position) { }

private readonly PkwareTraditionalEncryptionData _encryptor;
private readonly CryptoMode _mode;
private readonly Stream _stream;
Expand All @@ -25,6 +46,10 @@ CryptoMode mode
_encryptor = encryptor;
_stream = stream;
_mode = mode;

#if DEBUG_STREAMS
this.DebugConstruct(typeof(PkwareTraditionalCryptoStream));
#endif
}

public override bool CanRead => (_mode == CryptoMode.Decrypt);
Expand Down Expand Up @@ -100,6 +125,9 @@ protected override void Dispose(bool disposing)
return;
}
_isDisposed = true;
#if DEBUG_STREAMS
this.DebugDispose(typeof(PkwareTraditionalCryptoStream));
#endif
base.Dispose(disposing);
_stream.Dispose();
}
Expand Down
7 changes: 4 additions & 3 deletions src/SharpCompress/Common/Zip/StreamingZipFilePart.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ internal override Stream GetCompressedStream()
);
if (LeaveStreamOpen)
{
return NonDisposingStream.Create(_decompressionStream);
return SharpCompressStream.Create(_decompressionStream, leaveOpen: true);
}
return _decompressionStream;
}

internal BinaryReader FixStreamedFileLocation(ref RewindableStream rewindableStream)
internal BinaryReader FixStreamedFileLocation(ref SharpCompressStream rewindableStream)
{
if (Header.IsDirectory)
{
Expand All @@ -49,7 +49,8 @@ internal BinaryReader FixStreamedFileLocation(ref RewindableStream rewindableStr

if (_decompressionStream is DeflateStream deflateStream)
{
rewindableStream.Rewind(deflateStream.InputBuffer);
((IStreamStack)rewindableStream).StackSeek(0);
//rewindableStream.Rewind(deflateStream.InputBuffer);
}

Skipped = true;
Expand Down
Loading