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); + } + } + } } }