From 3375aaa90c4c72347861f21bdf00a4498572f5ae Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 24 Jul 2026 07:18:02 +0000 Subject: [PATCH] fix: preserve transformed streams in reader detection --- .../IO/SharpCompressStream.Create.cs | 14 +----- .../GZip/GZipArchiveTests.cs | 48 +++++++++++++++++++ 2 files changed, 50 insertions(+), 12 deletions(-) diff --git a/src/SharpCompress/IO/SharpCompressStream.Create.cs b/src/SharpCompress/IO/SharpCompressStream.Create.cs index 37d91ebf..645f5948 100644 --- a/src/SharpCompress/IO/SharpCompressStream.Create.cs +++ b/src/SharpCompress/IO/SharpCompressStream.Create.cs @@ -52,8 +52,8 @@ public partial class SharpCompressStream /// or to /// avoid this. /// Already-wrapped streams — if is already a - /// (or a stack that contains one), it is returned as-is to - /// prevent double-wrapping and double-buffering. + /// , it is returned as-is to prevent double-wrapping and + /// double-buffering. /// /// The underlying stream to wrap. Must not be . /// @@ -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(); - if (underlying is not null) - { - return underlying; - } - } - if (stream.CanSeek) { return new SeekableSharpCompressStream(stream); diff --git a/tests/SharpCompress.Test/GZip/GZipArchiveTests.cs b/tests/SharpCompress.Test/GZip/GZipArchiveTests.cs index 5f9f5094..c3737e98 100644 --- a/tests/SharpCompress.Test/GZip/GZipArchiveTests.cs +++ b/tests/SharpCompress.Test/GZip/GZipArchiveTests.cs @@ -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() {