未验证 提交 275c1e54 编写于 作者: D David Cantú 提交者: GitHub

SkipBlockAlignmentPadding must be executed for all entries (#74396)

上级 bd4bea62
......@@ -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);
}
}
......@@ -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);
}
}
......
......@@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using Xunit;
......@@ -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());
}
}
}
......@@ -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;
......@@ -174,5 +175,36 @@ await using (TarWriter writer = new TarWriter(archive, format, leaveOpen: true))
}
}
}
[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());
}
}
}
......@@ -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);
}
}
}
......@@ -288,5 +288,43 @@ await using (WrappedStream wrapped = new WrappedStream(archive, canRead: true, c
}
}
}
[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);
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册