Skip to content

Commit

Permalink
Fix some corner cases in TarReader (dotnet#74329)
Browse files Browse the repository at this point in the history
  • Loading branch information
am11 authored and carlossanlop committed Aug 23, 2022
1 parent ce89de8 commit eacdab2
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 7 deletions.
4 changes: 2 additions & 2 deletions eng/Version.Details.xml
Original file line number Diff line number Diff line change
Expand Up @@ -138,9 +138,9 @@
<Uri>https://github.com/dotnet/runtime-assets</Uri>
<Sha>555080fde81d34b38dfab27115c52f0a620803a2</Sha>
</Dependency>
<Dependency Name="System.Formats.Tar.TestData" Version="7.0.0-beta.22415.3">
<Dependency Name="System.Formats.Tar.TestData" Version="7.0.0-beta.22421.2">
<Uri>https://github.com/dotnet/runtime-assets</Uri>
<Sha>555080fde81d34b38dfab27115c52f0a620803a2</Sha>
<Sha>9d8fad5f0614bee808083308a3729084b681f7e7</Sha>
</Dependency>
<Dependency Name="System.IO.Compression.TestData" Version="7.0.0-beta.22415.3">
<Uri>https://github.com/dotnet/runtime-assets</Uri>
Expand Down
2 changes: 1 addition & 1 deletion eng/Versions.props
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@
<SystemRuntimeNumericsTestDataVersion>7.0.0-beta.22415.3</SystemRuntimeNumericsTestDataVersion>
<SystemComponentModelTypeConverterTestDataVersion>7.0.0-beta.22415.3</SystemComponentModelTypeConverterTestDataVersion>
<SystemDrawingCommonTestDataVersion>7.0.0-beta.22415.3</SystemDrawingCommonTestDataVersion>
<SystemFormatsTarTestDataVersion>7.0.0-beta.22415.3</SystemFormatsTarTestDataVersion>
<SystemFormatsTarTestDataVersion>7.0.0-beta.22421.2</SystemFormatsTarTestDataVersion>
<SystemIOCompressionTestDataVersion>7.0.0-beta.22415.3</SystemIOCompressionTestDataVersion>
<SystemIOPackagingTestDataVersion>7.0.0-beta.22415.3</SystemIOPackagingTestDataVersion>
<SystemNetTestDataVersion>7.0.0-beta.22415.3</SystemNetTestDataVersion>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -461,18 +461,36 @@ private void ReadVersionAttribute(Span<byte> buffer)
// The POSIX formats have a 6 byte Magic "ustar\0", followed by a 2 byte Version "00"
if (!version.SequenceEqual(UstarVersionBytes))
{
throw new FormatException(string.Format(SR.TarPosixFormatExpected, _name));
// Check for gnu version header for mixed case
if (!version.SequenceEqual(GnuVersionBytes))
{
throw new FormatException(string.Format(SR.TarPosixFormatExpected, _name));
}

_version = GnuVersion;
}
else
{
_version = UstarVersion;
}
_version = UstarVersion;
break;

case TarEntryFormat.Gnu:
// The GNU format has a Magic+Version 8 byte string "ustar \0"
if (!version.SequenceEqual(GnuVersionBytes))
{
throw new FormatException(string.Format(SR.TarGnuFormatExpected, _name));
// Check for ustar or pax version header for mixed case
if (!version.SequenceEqual(UstarVersionBytes))
{
throw new FormatException(string.Format(SR.TarGnuFormatExpected, _name));
}

_version = UstarVersion;
}
else
{
_version = GnuVersion;
}
_version = GnuVersion;
break;

default:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,11 @@ public async ValueTask DisposeAsync()
TarEntryFormat.V7 or TarEntryFormat.Unknown or _ => new V7TarEntry(header, this),
};

if (_archiveStream.CanSeek && _archiveStream.Length == _archiveStream.Position)
{
_reachedEndMarkers = true;
}

_previouslyReadEntry = entry;
PreserveDataStreamForDisposalIfNeeded(entry);
return entry;
Expand Down Expand Up @@ -291,6 +296,11 @@ internal async ValueTask AdvanceDataStreamIfNeededAsync(CancellationToken cancel
TarEntryFormat.V7 or TarEntryFormat.Unknown or _ => new V7TarEntry(header, this),
};

if (_archiveStream.CanSeek && _archiveStream.Length == _archiveStream.Position)
{
_reachedEndMarkers = true;
}

_previouslyReadEntry = entry;
PreserveDataStreamForDisposalIfNeeded(entry);
return entry;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,5 +124,31 @@ public void Read_Archive_LongFileName_Over100_Under255(TarEntryFormat format, Te
[InlineData(TarEntryFormat.Gnu, TestTarFormat.oldgnu)]
public void Read_Archive_LongPath_Over255(TarEntryFormat format, TestTarFormat testFormat) =>
Read_Archive_LongPath_Over255_Internal(format, testFormat);

[Fact]
public void Read_NodeTarArchives_Successfully()
{
string nodeTarPath = Path.Join(Directory.GetCurrentDirectory(), "tar", "node-tar");
foreach (string file in Directory.EnumerateFiles(nodeTarPath, "*.tar", SearchOption.AllDirectories))
{
using FileStream sourceStream = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read);
using var reader = new TarReader(sourceStream);

TarEntry? entry = null;
while (true)
{
Exception ex = Record.Exception(() => entry = reader.GetNextEntry());
Assert.Null(ex);

if (entry is null) break;

ex = Record.Exception(() => entry.Name);
Assert.Null(ex);

ex = Record.Exception(() => entry.Length);
Assert.Null(ex);
}
}
}
}
}

0 comments on commit eacdab2

Please sign in to comment.