Skip to content

Commit bfd9eb0

Browse files
authored
Fix some corner cases in TarReader (#74329)
1 parent 8cf96d9 commit bfd9eb0

File tree

5 files changed

+61
-7
lines changed

5 files changed

+61
-7
lines changed

eng/Version.Details.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,9 @@
134134
<Uri>https://github.com/dotnet/runtime-assets</Uri>
135135
<Sha>77acd39a813579e1e9b12cd98466787e7f90e059</Sha>
136136
</Dependency>
137-
<Dependency Name="System.Formats.Tar.TestData" Version="7.0.0-beta.22409.1">
137+
<Dependency Name="System.Formats.Tar.TestData" Version="7.0.0-beta.22421.2">
138138
<Uri>https://github.com/dotnet/runtime-assets</Uri>
139-
<Sha>77acd39a813579e1e9b12cd98466787e7f90e059</Sha>
139+
<Sha>9d8fad5f0614bee808083308a3729084b681f7e7</Sha>
140140
</Dependency>
141141
<Dependency Name="System.IO.Compression.TestData" Version="7.0.0-beta.22409.1">
142142
<Uri>https://github.com/dotnet/runtime-assets</Uri>

eng/Versions.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@
120120
<SystemRuntimeNumericsTestDataVersion>7.0.0-beta.22409.1</SystemRuntimeNumericsTestDataVersion>
121121
<SystemComponentModelTypeConverterTestDataVersion>7.0.0-beta.22409.1</SystemComponentModelTypeConverterTestDataVersion>
122122
<SystemDrawingCommonTestDataVersion>7.0.0-beta.22409.1</SystemDrawingCommonTestDataVersion>
123-
<SystemFormatsTarTestDataVersion>7.0.0-beta.22409.1</SystemFormatsTarTestDataVersion>
123+
<SystemFormatsTarTestDataVersion>7.0.0-beta.22421.2</SystemFormatsTarTestDataVersion>
124124
<SystemIOCompressionTestDataVersion>7.0.0-beta.22409.1</SystemIOCompressionTestDataVersion>
125125
<SystemIOPackagingTestDataVersion>7.0.0-beta.22409.1</SystemIOPackagingTestDataVersion>
126126
<SystemNetTestDataVersion>7.0.0-beta.22409.1</SystemNetTestDataVersion>

src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarHeader.Read.cs

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -461,18 +461,36 @@ private void ReadVersionAttribute(Span<byte> buffer)
461461
// The POSIX formats have a 6 byte Magic "ustar\0", followed by a 2 byte Version "00"
462462
if (!version.SequenceEqual(UstarVersionBytes))
463463
{
464-
throw new FormatException(string.Format(SR.TarPosixFormatExpected, _name));
464+
// Check for gnu version header for mixed case
465+
if (!version.SequenceEqual(GnuVersionBytes))
466+
{
467+
throw new FormatException(string.Format(SR.TarPosixFormatExpected, _name));
468+
}
469+
470+
_version = GnuVersion;
471+
}
472+
else
473+
{
474+
_version = UstarVersion;
465475
}
466-
_version = UstarVersion;
467476
break;
468477

469478
case TarEntryFormat.Gnu:
470479
// The GNU format has a Magic+Version 8 byte string "ustar \0"
471480
if (!version.SequenceEqual(GnuVersionBytes))
472481
{
473-
throw new FormatException(string.Format(SR.TarGnuFormatExpected, _name));
482+
// Check for ustar or pax version header for mixed case
483+
if (!version.SequenceEqual(UstarVersionBytes))
484+
{
485+
throw new FormatException(string.Format(SR.TarGnuFormatExpected, _name));
486+
}
487+
488+
_version = UstarVersion;
489+
}
490+
else
491+
{
492+
_version = GnuVersion;
474493
}
475-
_version = GnuVersion;
476494
break;
477495

478496
default:

src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarReader.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,11 @@ public async ValueTask DisposeAsync()
138138
TarEntryFormat.V7 or TarEntryFormat.Unknown or _ => new V7TarEntry(header, this),
139139
};
140140

141+
if (_archiveStream.CanSeek && _archiveStream.Length == _archiveStream.Position)
142+
{
143+
_reachedEndMarkers = true;
144+
}
145+
141146
_previouslyReadEntry = entry;
142147
PreserveDataStreamForDisposalIfNeeded(entry);
143148
return entry;
@@ -291,6 +296,11 @@ internal async ValueTask AdvanceDataStreamIfNeededAsync(CancellationToken cancel
291296
TarEntryFormat.V7 or TarEntryFormat.Unknown or _ => new V7TarEntry(header, this),
292297
};
293298

299+
if (_archiveStream.CanSeek && _archiveStream.Length == _archiveStream.Position)
300+
{
301+
_reachedEndMarkers = true;
302+
}
303+
294304
_previouslyReadEntry = entry;
295305
PreserveDataStreamForDisposalIfNeeded(entry);
296306
return entry;

src/libraries/System.Formats.Tar/tests/TarReader/TarReader.File.Tests.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,5 +124,31 @@ public void Read_Archive_LongFileName_Over100_Under255(TarEntryFormat format, Te
124124
[InlineData(TarEntryFormat.Gnu, TestTarFormat.oldgnu)]
125125
public void Read_Archive_LongPath_Over255(TarEntryFormat format, TestTarFormat testFormat) =>
126126
Read_Archive_LongPath_Over255_Internal(format, testFormat);
127+
128+
[Fact]
129+
public void Read_NodeTarArchives_Successfully()
130+
{
131+
string nodeTarPath = Path.Join(Directory.GetCurrentDirectory(), "tar", "node-tar");
132+
foreach (string file in Directory.EnumerateFiles(nodeTarPath, "*.tar", SearchOption.AllDirectories))
133+
{
134+
using FileStream sourceStream = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read);
135+
using var reader = new TarReader(sourceStream);
136+
137+
TarEntry? entry = null;
138+
while (true)
139+
{
140+
Exception ex = Record.Exception(() => entry = reader.GetNextEntry());
141+
Assert.Null(ex);
142+
143+
if (entry is null) break;
144+
145+
ex = Record.Exception(() => entry.Name);
146+
Assert.Null(ex);
147+
148+
ex = Record.Exception(() => entry.Length);
149+
Assert.Null(ex);
150+
}
151+
}
152+
}
127153
}
128154
}

0 commit comments

Comments
 (0)