Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
SkipBlockAlignmentPadding must be executed for all entries (#74396)
  • Loading branch information
jozkee authored and carlossanlop committed Aug 23, 2022
commit ce05de7c9ed535122e2e58aefd74b145142ea971
Original file line number Diff line number Diff line change
Expand Up @@ -225,10 +225,10 @@ internal void AdvanceDataStreamIfNeeded()
{
long bytesToSkip = _previouslyReadEntry._header._size - dataStream.Position;
TarHelpers.AdvanceStream(_archiveStream, bytesToSkip);
TarHelpers.SkipBlockAlignmentPadding(_archiveStream, _previouslyReadEntry._header._size);
dataStream.HasReachedEnd = true; // Now the pointer is beyond the limit, so any read attempts should throw
}
}
TarHelpers.SkipBlockAlignmentPadding(_archiveStream, _previouslyReadEntry._header._size);
}
}

Expand Down Expand Up @@ -267,10 +267,10 @@ internal async ValueTask AdvanceDataStreamIfNeededAsync(CancellationToken cancel
{
long bytesToSkip = _previouslyReadEntry._header._size - dataStream.Position;
await TarHelpers.AdvanceStreamAsync(_archiveStream, bytesToSkip, cancellationToken).ConfigureAwait(false);
await TarHelpers.SkipBlockAlignmentPaddingAsync(_archiveStream, _previouslyReadEntry._header._size, cancellationToken).ConfigureAwait(false);
dataStream.HasReachedEnd = true; // Now the pointer is beyond the limit, so any read attempts should throw
}
}
await TarHelpers.SkipBlockAlignmentPaddingAsync(_archiveStream, _previouslyReadEntry._header._size, cancellationToken).ConfigureAwait(false);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using Xunit;

Expand Down Expand Up @@ -145,5 +146,36 @@ private void Extract_LinkEntry_TargetInsideDirectory_Internal(TarEntryType entry

Assert.Equal(2, Directory.GetFileSystemEntries(baseDir).Count());
}

[Theory]
[InlineData(512)]
[InlineData(512 + 1)]
[InlineData(512 + 512 - 1)]
public void Extract_UnseekableStream_BlockAlignmentPadding_DoesNotAffectNextEntries(int contentSize)
{
byte[] fileContents = new byte[contentSize];
Array.Fill<byte>(fileContents, 0x1);

using var archive = new MemoryStream();
using (var compressor = new GZipStream(archive, CompressionMode.Compress, leaveOpen: true))
{
using var writer = new TarWriter(compressor);
var entry1 = new PaxTarEntry(TarEntryType.RegularFile, "file");
entry1.DataStream = new MemoryStream(fileContents);
writer.WriteEntry(entry1);

var entry2 = new PaxTarEntry(TarEntryType.RegularFile, "next-file");
writer.WriteEntry(entry2);
}

archive.Position = 0;
using var decompressor = new GZipStream(archive, CompressionMode.Decompress);
using var reader = new TarReader(decompressor);

using TempDirectory destination = new TempDirectory();
TarFile.ExtractToDirectory(decompressor, destination.Path, overwriteFiles: true);

Assert.Equal(2, Directory.GetFileSystemEntries(destination.Path, "*", SearchOption.AllDirectories).Count());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
Expand Down Expand Up @@ -174,5 +175,36 @@ private async Task Extract_LinkEntry_TargetInsideDirectory_Internal_Async(TarEnt
}
}
}

[Theory]
[InlineData(512)]
[InlineData(512 + 1)]
[InlineData(512 + 512 - 1)]
public async Task Extract_UnseekableStream_BlockAlignmentPadding_DoesNotAffectNextEntries_Async(int contentSize)
{
byte[] fileContents = new byte[contentSize];
Array.Fill<byte>(fileContents, 0x1);

using var archive = new MemoryStream();
using (var compressor = new GZipStream(archive, CompressionMode.Compress, leaveOpen: true))
{
using var writer = new TarWriter(compressor);
var entry1 = new PaxTarEntry(TarEntryType.RegularFile, "file");
entry1.DataStream = new MemoryStream(fileContents);
await writer.WriteEntryAsync(entry1);

var entry2 = new PaxTarEntry(TarEntryType.RegularFile, "next-file");
await writer.WriteEntryAsync(entry2);
}

archive.Position = 0;
using var decompressor = new GZipStream(archive, CompressionMode.Decompress);
using var reader = new TarReader(decompressor);

using TempDirectory destination = new TempDirectory();
await TarFile.ExtractToDirectoryAsync(decompressor, destination.Path, overwriteFiles: true);

Assert.Equal(2, Directory.GetFileSystemEntries(destination.Path, "*", SearchOption.AllDirectories).Count());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -250,5 +250,43 @@ public void GetNextEntry_UnseekableArchive_ReplaceDataStream_ExcludeFromDisposin
Assert.Equal("Substituted", streamReader.ReadLine());
}
}

[Theory]
[InlineData(512)]
[InlineData(512 + 1)]
[InlineData(512 + 512 - 1)]
public void BlockAlignmentPadding_DoesNotAffectNextEntries(int contentSize)
{
byte[] fileContents = new byte[contentSize];
Array.Fill<byte>(fileContents, 0x1);

using var archive = new MemoryStream();
using (var writer = new TarWriter(archive, leaveOpen: true))
{
var entry1 = new PaxTarEntry(TarEntryType.RegularFile, "file");
entry1.DataStream = new MemoryStream(fileContents);
writer.WriteEntry(entry1);

var entry2 = new PaxTarEntry(TarEntryType.RegularFile, "next-file");
writer.WriteEntry(entry2);
}

archive.Position = 0;
using var unseekable = new WrappedStream(archive, archive.CanRead, archive.CanWrite, canSeek: false);
using var reader = new TarReader(unseekable);

TarEntry e = reader.GetNextEntry();
Assert.Equal(contentSize, e.Length);

byte[] buffer = new byte[contentSize];
while (e.DataStream.Read(buffer) > 0) ;
AssertExtensions.SequenceEqual(fileContents, buffer);

e = reader.GetNextEntry();
Assert.Equal(0, e.Length);

e = reader.GetNextEntry();
Assert.Null(e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -288,5 +288,43 @@ public async Task GetNextEntry_UnseekableArchive_ReplaceDataStream_ExcludeFromDi
}
}
}

[Theory]
[InlineData(512)]
[InlineData(512 + 1)]
[InlineData(512 + 512 - 1)]
public async Task BlockAlignmentPadding_DoesNotAffectNextEntries_Async(int contentSize)
{
byte[] fileContents = new byte[contentSize];
Array.Fill<byte>(fileContents, 0x1);

using var archive = new MemoryStream();
using (var writer = new TarWriter(archive, leaveOpen: true))
{
var entry1 = new PaxTarEntry(TarEntryType.RegularFile, "file");
entry1.DataStream = new MemoryStream(fileContents);
await writer.WriteEntryAsync(entry1);

var entry2 = new PaxTarEntry(TarEntryType.RegularFile, "next-file");
await writer.WriteEntryAsync(entry2);
}

archive.Position = 0;
using var unseekable = new WrappedStream(archive, archive.CanRead, archive.CanWrite, canSeek: false);
using var reader = new TarReader(unseekable);

TarEntry e = await reader.GetNextEntryAsync();
Assert.Equal(contentSize, e.Length);

byte[] buffer = new byte[contentSize];
while (e.DataStream.Read(buffer) > 0) ;
AssertExtensions.SequenceEqual(fileContents, buffer);

e = await reader.GetNextEntryAsync();
Assert.Equal(0, e.Length);

e = await reader.GetNextEntryAsync();
Assert.Null(e);
}
}
}