diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml
index 60e41e70423b9..d416a1945968e 100644
--- a/eng/Version.Details.xml
+++ b/eng/Version.Details.xml
@@ -134,9 +134,9 @@
https://github.com/dotnet/runtime-assets
77acd39a813579e1e9b12cd98466787e7f90e059
-
+
https://github.com/dotnet/runtime-assets
- 77acd39a813579e1e9b12cd98466787e7f90e059
+ 9d8fad5f0614bee808083308a3729084b681f7e7
https://github.com/dotnet/runtime-assets
diff --git a/eng/Versions.props b/eng/Versions.props
index 20acfc0c0b7a2..a1275980cd4da 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -120,7 +120,7 @@
7.0.0-beta.22409.1
7.0.0-beta.22409.1
7.0.0-beta.22409.1
- 7.0.0-beta.22409.1
+ 7.0.0-beta.22421.2
7.0.0-beta.22409.1
7.0.0-beta.22409.1
7.0.0-beta.22409.1
diff --git a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarHeader.Read.cs b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarHeader.Read.cs
index f826a2c1e1b09..e43ae6973607d 100644
--- a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarHeader.Read.cs
+++ b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarHeader.Read.cs
@@ -461,18 +461,36 @@ private void ReadVersionAttribute(Span 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:
diff --git a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarReader.cs b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarReader.cs
index 137acbcfbd2d0..10f3f2524d1ca 100644
--- a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarReader.cs
+++ b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarReader.cs
@@ -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;
@@ -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;
diff --git a/src/libraries/System.Formats.Tar/tests/TarReader/TarReader.File.Tests.cs b/src/libraries/System.Formats.Tar/tests/TarReader/TarReader.File.Tests.cs
index ffc537917fc7a..5e35c12c3aaac 100644
--- a/src/libraries/System.Formats.Tar/tests/TarReader/TarReader.File.Tests.cs
+++ b/src/libraries/System.Formats.Tar/tests/TarReader/TarReader.File.Tests.cs
@@ -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);
+ }
+ }
+ }
}
}