fixed providers in TarWriter and TarArchive.

This commit is contained in:
Adam Hathcock
2026-04-30 14:12:47 +01:00
parent 2f3d11ca61
commit 48afb4da92
4 changed files with 74 additions and 70 deletions

View File

@@ -58,7 +58,7 @@ public partial class TarArchive
);
var compressionType = TarFactory.GetCompressionType(
sourceStream,
sourceStream.ReaderOptions.Providers
sourceStream.ReaderOptions
);
sourceStream.Seek(0, SeekOrigin.Begin);
return new TarArchive(sourceStream, compressionType);
@@ -78,7 +78,7 @@ public partial class TarArchive
);
var compressionType = TarFactory.GetCompressionType(
sourceStream,
sourceStream.ReaderOptions.Providers
sourceStream.ReaderOptions
);
sourceStream.Seek(0, SeekOrigin.Begin);
return new TarArchive(sourceStream, compressionType);
@@ -112,11 +112,7 @@ public partial class TarArchive
readerOptions ?? new ReaderOptions()
);
var compressionType = await TarFactory
.GetCompressionTypeAsync(
sourceStream,
sourceStream.ReaderOptions.Providers,
cancellationToken
)
.GetCompressionTypeAsync(sourceStream, sourceStream.ReaderOptions, cancellationToken)
.ConfigureAwait(false);
sourceStream.Seek(0, SeekOrigin.Begin);
return new TarArchive(sourceStream, compressionType);
@@ -144,11 +140,7 @@ public partial class TarArchive
readerOptions ??= new ReaderOptions() { LeaveStreamOpen = false };
var sourceStream = new SourceStream(fileInfo, i => null, readerOptions);
var compressionType = await TarFactory
.GetCompressionTypeAsync(
sourceStream,
sourceStream.ReaderOptions.Providers,
cancellationToken
)
.GetCompressionTypeAsync(sourceStream, sourceStream.ReaderOptions, cancellationToken)
.ConfigureAwait(false);
sourceStream.Seek(0, SeekOrigin.Begin);
return new TarArchive(sourceStream, compressionType);
@@ -169,11 +161,7 @@ public partial class TarArchive
readerOptions ?? new ReaderOptions()
);
var compressionType = await TarFactory
.GetCompressionTypeAsync(
sourceStream,
sourceStream.ReaderOptions.Providers,
cancellationToken
)
.GetCompressionTypeAsync(sourceStream, sourceStream.ReaderOptions, cancellationToken)
.ConfigureAwait(false);
sourceStream.Seek(0, SeekOrigin.Begin);
return new TarArchive(sourceStream, compressionType);
@@ -194,11 +182,7 @@ public partial class TarArchive
readerOptions ?? new ReaderOptions() { LeaveStreamOpen = false }
);
var compressionType = await TarFactory
.GetCompressionTypeAsync(
sourceStream,
sourceStream.ReaderOptions.Providers,
cancellationToken
)
.GetCompressionTypeAsync(sourceStream, sourceStream.ReaderOptions, cancellationToken)
.ConfigureAwait(false);
sourceStream.Seek(0, SeekOrigin.Begin);
return new TarArchive(sourceStream, compressionType);

View File

@@ -50,7 +50,6 @@ public class TarFactory
/// <inheritdoc/>
public override bool IsArchive(Stream stream, string? password = null)
{
var providers = CompressionProviderRegistry.Default;
var sharpCompressStream = new SharpCompressStream(stream);
sharpCompressStream.StartRecording(TarWrapper.MaximumRewindBufferSize);
foreach (var wrapper in TarWrapper.Wrappers)
@@ -61,8 +60,7 @@ public class TarFactory
sharpCompressStream.Rewind();
var decompressedStream = CreateProbeDecompressionStream(
sharpCompressStream,
wrapper.CompressionType,
providers
wrapper.CompressionType
);
if (TarArchive.IsTarFile(decompressedStream))
{
@@ -82,7 +80,6 @@ public class TarFactory
CancellationToken cancellationToken = default
)
{
var providers = CompressionProviderRegistry.Default;
var sharpCompressStream = new SharpCompressStream(stream);
sharpCompressStream.StartRecording(TarWrapper.MaximumRewindBufferSize);
foreach (var wrapper in TarWrapper.Wrappers)
@@ -98,7 +95,6 @@ public class TarFactory
var decompressedStream = await CreateProbeDecompressionStreamAsync(
sharpCompressStream,
wrapper.CompressionType,
providers,
cancellationToken: cancellationToken
)
.ConfigureAwait(false);
@@ -122,10 +118,10 @@ public class TarFactory
private static Stream CreateProbeDecompressionStream(
Stream stream,
CompressionType compressionType,
CompressionProviderRegistry providers,
IReaderOptions? readerOptions = null
)
{
var providers = readerOptions?.Providers ?? CompressionProviderRegistry.Default;
var nonDisposingStream = SharpCompressStream.CreateNonDisposing(stream);
if (compressionType == CompressionType.None)
{
@@ -147,7 +143,6 @@ public class TarFactory
private static async ValueTask<Stream> CreateProbeDecompressionStreamAsync(
Stream stream,
CompressionType compressionType,
CompressionProviderRegistry providers,
IReaderOptions? readerOptions = null,
CancellationToken cancellationToken = default
)
@@ -157,6 +152,7 @@ public class TarFactory
{
return nonDisposingStream;
}
var providers = readerOptions?.Providers ?? CompressionProviderRegistry.Default;
if (compressionType == CompressionType.GZip && readerOptions is not null)
{
@@ -179,10 +175,9 @@ public class TarFactory
public static CompressionType GetCompressionType(
Stream stream,
CompressionProviderRegistry? providers = null
IReaderOptions? readerOptions = null
)
{
providers ??= CompressionProviderRegistry.Default;
stream.Seek(0, SeekOrigin.Begin);
foreach (var wrapper in TarWrapper.Wrappers)
{
@@ -193,7 +188,7 @@ public class TarFactory
var decompressedStream = CreateProbeDecompressionStream(
stream,
wrapper.CompressionType,
providers
readerOptions
);
if (TarArchive.IsTarFile(decompressedStream))
{
@@ -206,11 +201,10 @@ public class TarFactory
public static async ValueTask<CompressionType> GetCompressionTypeAsync(
Stream stream,
CompressionProviderRegistry? providers = null,
IReaderOptions? readerOptions = null,
CancellationToken cancellationToken = default
)
{
providers ??= CompressionProviderRegistry.Default;
stream.Seek(0, SeekOrigin.Begin);
foreach (var wrapper in TarWrapper.Wrappers)
{
@@ -221,7 +215,7 @@ public class TarFactory
var decompressedStream = await CreateProbeDecompressionStreamAsync(
stream,
wrapper.CompressionType,
providers,
readerOptions,
cancellationToken: cancellationToken
)
.ConfigureAwait(false);
@@ -329,7 +323,6 @@ public class TarFactory
var decompressedStream = CreateProbeDecompressionStream(
sharpCompressStream,
wrapper.CompressionType,
options.Providers,
options
);
if (TarArchive.IsTarFile(decompressedStream))
@@ -366,7 +359,6 @@ public class TarFactory
var decompressedStream = await CreateProbeDecompressionStreamAsync(
sharpCompressStream,
wrapper.CompressionType,
options.Providers,
options,
cancellationToken
)
@@ -409,35 +401,6 @@ public class TarFactory
{
throw new ArgumentException("Tars require writable streams.");
}
if (writerOptions.LeaveStreamOpen)
{
stream = SharpCompressStream.CreateNonDisposing(stream);
}
var providers = writerOptions.Providers;
stream = writerOptions.CompressionType switch
{
CompressionType.None => stream,
CompressionType.BZip2 => providers.CreateCompressStream(
CompressionType.BZip2,
stream,
writerOptions.CompressionLevel
),
CompressionType.GZip => providers.CreateCompressStream(
CompressionType.GZip,
stream,
writerOptions.CompressionLevel
),
CompressionType.LZip => providers.CreateCompressStream(
CompressionType.LZip,
stream,
writerOptions.CompressionLevel
),
_ => throw new InvalidFormatException(
"Tar does not support compression: " + writerOptions.CompressionType
),
};
return new TarWriter(stream, tarOptions);
}
@@ -501,7 +464,7 @@ public class TarFactory
"Tar does not support compression: " + writerOptions.CompressionType
),
};
return new TarWriter(stream, tarOptions);
return new TarWriter(stream, tarOptions, streamIsPrepared: true);
}
#endregion

View File

@@ -31,7 +31,14 @@ public partial class TarWriter
{
await finishable.FinishAsync().ConfigureAwait(false);
}
OutputStream?.Dispose();
if (OutputStream is IAsyncDisposable asyncDisposableOutputStream)
{
await asyncDisposableOutputStream.DisposeAsync().ConfigureAwait(false);
}
else
{
OutputStream?.Dispose();
}
// base.DisposeAsync() is a no-op since _isDisposed is already set
await base.DisposeAsync().ConfigureAwait(false);
}

View File

@@ -2,6 +2,8 @@ using System;
using System.IO;
using SharpCompress.Common;
using SharpCompress.Common.Tar.Headers;
using SharpCompress.Compressors;
using SharpCompress.IO;
using SharpCompress.Providers;
namespace SharpCompress.Writers.Tar;
@@ -12,12 +14,60 @@ public partial class TarWriter : AbstractWriter
private readonly TarHeaderWriteFormat _headerFormat;
public TarWriter(Stream destination, TarWriterOptions options)
: base(ArchiveType.Tar, options)
: base(ArchiveType.Tar, GetEffectiveOptions(options))
{
_finalizeArchiveOnClose = options.FinalizeArchiveOnClose;
_headerFormat = options.HeaderFormat;
InitializeStream(destination);
InitializeStream(CreateOutputStream(destination, options));
}
internal TarWriter(Stream destination, TarWriterOptions options, bool streamIsPrepared)
: base(ArchiveType.Tar, GetEffectiveOptions(options))
{
_finalizeArchiveOnClose = options.FinalizeArchiveOnClose;
_headerFormat = options.HeaderFormat;
InitializeStream(streamIsPrepared ? destination : CreateOutputStream(destination, options));
}
private static TarWriterOptions GetEffectiveOptions(TarWriterOptions options) =>
options with
{
CompressionType = CompressionType.None,
LeaveStreamOpen = false,
};
private static Stream CreateOutputStream(Stream destination, TarWriterOptions options)
{
if (options.LeaveStreamOpen)
{
destination = SharpCompressStream.CreateNonDisposing(destination);
}
var providers = options.Providers;
return options.CompressionType switch
{
CompressionType.None => destination,
CompressionType.BZip2 => providers.CreateCompressStream(
CompressionType.BZip2,
destination,
options.CompressionLevel
),
CompressionType.GZip => providers.CreateCompressStream(
CompressionType.GZip,
destination,
options.CompressionLevel
),
CompressionType.LZip => providers.CreateCompressStream(
CompressionType.LZip,
destination,
options.CompressionLevel
),
_ => throw new InvalidFormatException(
"Tar does not support compression: " + options.CompressionType
),
};
}
public override void Write(string filename, Stream source, DateTime? modificationTime) =>