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 6231acd3ff381..5036a59334d85 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 @@ -733,12 +733,6 @@ private static bool TryGetNextExtendedAttribute( ReadOnlySpan keySlice = line.Slice(0, equalPos); ReadOnlySpan valueSlice = line.Slice(equalPos + 1); - // If the value contains an =, it's malformed. - if (valueSlice.IndexOf((byte)'=') >= 0) - { - return false; - } - // Return the parsed key and value. key = Encoding.UTF8.GetString(keySlice); value = Encoding.UTF8.GetString(valueSlice); diff --git a/src/libraries/System.Formats.Tar/tests/TarReader/TarReader.File.GlobalExtendedAttributes.Tests.cs b/src/libraries/System.Formats.Tar/tests/TarReader/TarReader.File.GlobalExtendedAttributes.Tests.cs index 755f3377703fc..7c25ba67b657f 100644 --- a/src/libraries/System.Formats.Tar/tests/TarReader/TarReader.File.GlobalExtendedAttributes.Tests.cs +++ b/src/libraries/System.Formats.Tar/tests/TarReader/TarReader.File.GlobalExtendedAttributes.Tests.cs @@ -84,12 +84,7 @@ public void ExtractGlobalExtendedAttributesEntry_Throws() } [Theory] - [InlineData("key", "value")] - [InlineData("key ", "value ")] - [InlineData(" key", " value")] - [InlineData(" key ", " value ")] - [InlineData(" key spaced ", " value spaced ")] - [InlineData("many sla/s\\hes", "/////////////\\\\\\///////////")] + [MemberData(nameof(GetPaxExtendedAttributesRoundtripTestData))] public void GlobalExtendedAttribute_Roundtrips(string key, string value) { var stream = new MemoryStream(); @@ -104,6 +99,7 @@ public void GlobalExtendedAttribute_Roundtrips(string key, string value) PaxGlobalExtendedAttributesTarEntry entry = Assert.IsType(reader.GetNextEntry()); Assert.Equal(1, entry.GlobalExtendedAttributes.Count); Assert.Equal(KeyValuePair.Create(key, value), entry.GlobalExtendedAttributes.First()); + Assert.Null(reader.GetNextEntry()); } } } 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 f1eaa4269a773..6b5dae94caf6b 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 @@ -333,30 +333,6 @@ public void PaxSizeLargerThanMaxAllowedByStream() Assert.Throws(() => reader.GetNextEntry()); } - [Theory] - [InlineData("key", "value")] - [InlineData("key ", "value ")] - [InlineData(" key", " value")] - [InlineData(" key ", " value ")] - [InlineData(" key spaced ", " value spaced ")] - [InlineData("many sla/s\\hes", "/////////////\\\\\\///////////")] - public void PaxExtendedAttribute_Roundtrips(string key, string value) - { - var stream = new MemoryStream(); - using (var writer = new TarWriter(stream, leaveOpen: true)) - { - writer.WriteEntry(new PaxTarEntry(TarEntryType.Directory, "entryName", new Dictionary() { { key, value } })); - } - - stream.Position = 0; - using (var reader = new TarReader(stream)) - { - PaxTarEntry entry = Assert.IsType(reader.GetNextEntry()); - Assert.Equal(5, entry.ExtendedAttributes.Count); - Assert.Contains(KeyValuePair.Create(key, value), entry.ExtendedAttributes); - } - } - private static void VerifyDataStreamOfTarUncompressedInternal(string testFolderName, string testCaseName, bool copyData) { using MemoryStream archiveStream = GetTarMemoryStream(CompressionMethod.Uncompressed, testFolderName, testCaseName); diff --git a/src/libraries/System.Formats.Tar/tests/TarReader/TarReader.Tests.cs b/src/libraries/System.Formats.Tar/tests/TarReader/TarReader.Tests.cs index 479b43380939f..f95a22335a141 100644 --- a/src/libraries/System.Formats.Tar/tests/TarReader/TarReader.Tests.cs +++ b/src/libraries/System.Formats.Tar/tests/TarReader/TarReader.Tests.cs @@ -98,5 +98,25 @@ public void TarReader_LeaveOpen_False_CopiedDataNotDisposed() ds.Dispose(); } } + + [Theory] + [MemberData(nameof(GetPaxExtendedAttributesRoundtripTestData))] + public void PaxExtendedAttribute_Roundtrips(string key, string value) + { + var stream = new MemoryStream(); + using (var writer = new TarWriter(stream, leaveOpen: true)) + { + writer.WriteEntry(new PaxTarEntry(TarEntryType.Directory, "entryName", new Dictionary() { { key, value } })); + } + + stream.Position = 0; + using (var reader = new TarReader(stream)) + { + PaxTarEntry entry = Assert.IsType(reader.GetNextEntry()); + Assert.Equal(5, entry.ExtendedAttributes.Count); + Assert.Contains(KeyValuePair.Create(key, value), entry.ExtendedAttributes); + Assert.Null(reader.GetNextEntry()); + } + } } } diff --git a/src/libraries/System.Formats.Tar/tests/TarTestsBase.Pax.cs b/src/libraries/System.Formats.Tar/tests/TarTestsBase.Pax.cs index dd71b15796396..c1776753512cf 100644 --- a/src/libraries/System.Formats.Tar/tests/TarTestsBase.Pax.cs +++ b/src/libraries/System.Formats.Tar/tests/TarTestsBase.Pax.cs @@ -124,5 +124,21 @@ protected void VerifyExtendedAttributeTimestamps(PaxTarEntry pax) VerifyExtendedAttributeTimestamp(pax, PaxEaATime, MinimumTime); VerifyExtendedAttributeTimestamp(pax, PaxEaCTime, MinimumTime); } + + public static IEnumerable GetPaxExtendedAttributesRoundtripTestData() + { + yield return new object[] { "key", "value" }; + yield return new object[] { "key ", "value " }; + yield return new object[] { " key", " value" }; + yield return new object[] { " key ", " value " }; + yield return new object[] { " key spaced ", " value spaced " }; + yield return new object[] { "many sla/s\\hes", "/////////////\\\\\\///////////" }; + yield return new object[] { "key", "=" }; + yield return new object[] { "key", "=value" }; + yield return new object[] { "key", "va=lue" }; + yield return new object[] { "key", "value=" }; + // real world scenario + yield return new object[] { "MSWINDOWS.rawsd", "AQAAgBQAAAAkAAAAAAAAAAAAAAABAgAAAAAABSAAAAAhAgAAAQIAAAAAAAUgAAAAIQIAAA==" }; + } } }