fix: preserve transformed streams in reader detection

This commit is contained in:
copilot-swe-agent[bot]
2026-07-24 07:18:02 +00:00
committed by GitHub
parent 0bb5b62842
commit 3375aaa90c
2 changed files with 50 additions and 12 deletions

View File

@@ -52,8 +52,8 @@ public partial class SharpCompressStream
/// <paramref name="bufferSize"/> or <see cref="Common.Constants.RewindableBufferSize"/> to
/// avoid this.</para>
/// <para><b>Already-wrapped streams</b> — if <paramref name="stream"/> is already a
/// <see cref="SharpCompressStream"/> (or a stack that contains one), it is returned as-is to
/// prevent double-wrapping and double-buffering.</para>
/// <see cref="SharpCompressStream"/>, it is returned as-is to prevent double-wrapping and
/// double-buffering.</para>
/// </remarks>
/// <param name="stream">The underlying stream to wrap. Must not be <see langword="null"/>.</param>
/// <param name="bufferSize">
@@ -90,16 +90,6 @@ public partial class SharpCompressStream
return sharpCompressStream;
}
// Check if stream is wrapping a SharpCompressStream (e.g., via IStreamStack)
if (stream is IStreamStack streamStack)
{
var underlying = streamStack.GetStream<SharpCompressStream>();
if (underlying is not null)
{
return underlying;
}
}
if (stream.CanSeek)
{
return new SeekableSharpCompressStream(stream);

View File

@@ -5,8 +5,13 @@ using SharpCompress.Archives;
using SharpCompress.Archives.GZip;
using SharpCompress.Archives.Tar;
using SharpCompress.Common;
using SharpCompress.Compressors;
using SharpCompress.Compressors.Deflate;
using SharpCompress.Readers;
using SharpCompress.Test.Mocks;
using SharpCompress.Writers;
using SharpCompress.Writers.GZip;
using SharpCompress.Writers.Tar;
using Xunit;
namespace SharpCompress.Test.GZip;
@@ -108,6 +113,49 @@ public class GZipArchiveTests : ArchiveTests
Assert.Equal(size, tarStream.Length);
}
[Fact]
public void GZip_Archive_EntryStream_Can_Be_Opened_As_Tar_Reader()
{
var sourceDirectory = Path.Combine(SCRATCH_FILES_PATH, "srcdir");
Directory.CreateDirectory(sourceDirectory);
File.WriteAllText(Path.Combine(sourceDirectory, "a.txt"), "i am a.txt");
var subDirectory = Path.Combine(sourceDirectory, "sub");
Directory.CreateDirectory(subDirectory);
File.WriteAllText(Path.Combine(subDirectory, "suba.txt"), "i am suba.txt");
var archivePath = Path.Combine(SCRATCH_FILES_PATH, "srcdir.tar.gz");
using (var fileStream = File.Create(archivePath))
using (var gzipStream = new GZipStream(fileStream, CompressionMode.Compress))
using (var tarArchive = TarArchive.CreateArchive())
{
tarArchive.AddAllFromDirectory(sourceDirectory, "*", SearchOption.AllDirectories);
tarArchive.SaveTo(gzipStream, new TarWriterOptions(CompressionType.None, false));
}
var destinationDirectory = Path.Combine(SCRATCH_FILES_PATH, "destdir");
Directory.CreateDirectory(destinationDirectory);
using var archive = GZipArchive.OpenArchive(archivePath);
using var entryStream = archive.Entries.First().OpenEntryStream();
using var reader = ReaderFactory.OpenReader(entryStream);
while (reader.MoveToNextEntry())
{
if (!reader.Entry.IsDirectory && reader.Entry.Size > 0)
{
reader.WriteEntryToDirectory(
destinationDirectory,
new ExtractionOptions { ExtractFullPath = true, Overwrite = true }
);
}
}
Assert.Equal("i am a.txt", File.ReadAllText(Path.Combine(destinationDirectory, "a.txt")));
Assert.Equal(
"i am suba.txt",
File.ReadAllText(Path.Combine(destinationDirectory, "sub", "suba.txt"))
);
}
[Fact]
public void TestGzCrcWithMostSignificantBitNotNegative()
{