diff --git a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarWriter.cs b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarWriter.cs index a9efcf84b5240..4d715cdd6b330 100644 --- a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarWriter.cs +++ b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarWriter.cs @@ -311,7 +311,6 @@ private void WriteFinalRecords() byte[] emptyRecord = new byte[TarHelpers.RecordSize]; _archiveStream.Write(emptyRecord); _archiveStream.Write(emptyRecord); - _archiveStream.SetLength(_archiveStream.Position); } // Partial method for reading an entry from disk and writing it into the archive stream. diff --git a/src/libraries/System.Formats.Tar/tests/CompressedTar.Tests.cs b/src/libraries/System.Formats.Tar/tests/CompressedTar.Tests.cs new file mode 100644 index 0000000000000..a056bc0eed9c7 --- /dev/null +++ b/src/libraries/System.Formats.Tar/tests/CompressedTar.Tests.cs @@ -0,0 +1,80 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.IO.Compression; +using System.IO; +using Xunit; + +namespace System.Formats.Tar.Tests +{ + public class CompressedTar_Tests : TarTestsBase + { + [Fact] + public void TarGz_TarWriter_TarReader() + { + using TempDirectory root = new TempDirectory(); + + string archivePath = Path.Join(root.Path, "compressed.tar.gz"); + + string fileName = "file.txt"; + string filePath = Path.Join(root.Path, fileName); + File.Create(filePath).Dispose(); + + // Create tar.gz archive + using (FileStream streamToCompress = File.Create(archivePath)) + { + using GZipStream compressorStream = new GZipStream(streamToCompress, CompressionMode.Compress); + using TarWriter writer = new TarWriter(compressorStream); + writer.WriteEntry(fileName: filePath, entryName: fileName); + } + FileInfo fileInfo = new FileInfo(archivePath); + Assert.True(fileInfo.Exists); + Assert.True(fileInfo.Length > 0); + + // Verify tar.gz archive contents + using (FileStream streamToDecompress = File.OpenRead(archivePath)) + { + using GZipStream decompressorStream = new GZipStream(streamToDecompress, CompressionMode.Decompress); + using TarReader reader = new TarReader(decompressorStream); + TarEntry entry = reader.GetNextEntry(); + Assert.Equal(TarFormat.Pax, reader.Format); + Assert.Equal(fileName, entry.Name); + Assert.Null(reader.GetNextEntry()); + } + } + + [Fact] + public void TarGz_TarFile_CreateFromDir_ExtractToDir() + { + using TempDirectory root = new TempDirectory(); + + string archivePath = Path.Join(root.Path, "compressed.tar.gz"); + + string sourceDirectory = Path.Join(root.Path, "source"); + Directory.CreateDirectory(sourceDirectory); + + string destinationDirectory = Path.Join(root.Path, "destination"); + Directory.CreateDirectory(destinationDirectory); + + string fileName = "file.txt"; + string filePath = Path.Join(sourceDirectory, fileName); + File.Create(filePath).Dispose(); + + using (FileStream streamToCompress = File.Create(archivePath)) + { + using GZipStream compressorStream = new GZipStream(streamToCompress, CompressionMode.Compress); + TarFile.CreateFromDirectory(sourceDirectory, compressorStream, includeBaseDirectory: false); + } + FileInfo fileInfo = new FileInfo(archivePath); + Assert.True(fileInfo.Exists); + Assert.True(fileInfo.Length > 0); + + using (FileStream streamToDecompress = File.OpenRead(archivePath)) + { + using GZipStream decompressorStream = new GZipStream(streamToDecompress, CompressionMode.Decompress); + TarFile.ExtractToDirectory(decompressorStream, destinationDirectory, overwriteFiles: true); + Assert.True(File.Exists(filePath)); + } + } + } +} \ No newline at end of file diff --git a/src/libraries/System.Formats.Tar/tests/System.Formats.Tar.Tests.csproj b/src/libraries/System.Formats.Tar/tests/System.Formats.Tar.Tests.csproj index d41bc4a1f1d11..3b53355dd6b46 100644 --- a/src/libraries/System.Formats.Tar/tests/System.Formats.Tar.Tests.csproj +++ b/src/libraries/System.Formats.Tar/tests/System.Formats.Tar.Tests.csproj @@ -8,6 +8,7 @@ + diff --git a/src/libraries/System.Formats.Tar/tests/TarWriter/TarWriter.Tests.cs b/src/libraries/System.Formats.Tar/tests/TarWriter/TarWriter.Tests.cs index 6b75ac5655d2d..855d52d9bcad3 100644 --- a/src/libraries/System.Formats.Tar/tests/TarWriter/TarWriter.Tests.cs +++ b/src/libraries/System.Formats.Tar/tests/TarWriter/TarWriter.Tests.cs @@ -79,6 +79,29 @@ public void Constructor_NoEntryInsertion_WritesNothing() Assert.Equal(0, archiveStream.Length); } + [Fact] + public void Write_To_UnseekableStream() + { + using MemoryStream inner = new MemoryStream(); + using WrappedStream wrapped = new WrappedStream(inner, canRead: true, canWrite: true, canSeek: false); + + using (TarWriter writer = new TarWriter(wrapped, leaveOpen: true)) + { + PaxTarEntry paxEntry = new PaxTarEntry(TarEntryType.RegularFile, "file.txt"); + writer.WriteEntry(paxEntry); + } // The final records should get written, and the length should not be set because position cannot be read + + inner.Seek(0, SeekOrigin.Begin); // Rewind the base stream (wrapped cannot be rewound) + + using (TarReader reader = new TarReader(wrapped)) + { + TarEntry entry = reader.GetNextEntry(); + Assert.Equal(TarFormat.Pax, reader.Format); + Assert.Equal(TarEntryType.RegularFile, entry.EntryType); + Assert.Null(reader.GetNextEntry()); + } + } + [Fact] public void VerifyChecksumV7() {