From a930ea82ecbc14729c99143871fbc94ce77bf62c Mon Sep 17 00:00:00 2001 From: carlossanlop Date: Tue, 28 Feb 2023 17:28:43 -0800 Subject: [PATCH 1/5] Move PaxExtendedAttribute_Roundtrips test to correct source code file. It is not handling any filesystem entries. --- .../tests/TarReader/TarReader.File.Tests.cs | 24 ------------------- .../tests/TarReader/TarReader.Tests.cs | 24 +++++++++++++++++++ 2 files changed, 24 insertions(+), 24 deletions(-) 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..d232441608c05 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,29 @@ public void TarReader_LeaveOpen_False_CopiedDataNotDisposed() ds.Dispose(); } } + + [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); + } + } } } From bffa06515ebbb51cb0ea882be3fc4e25548048d1 Mon Sep 17 00:00:00 2001 From: carlossanlop Date: Tue, 28 Feb 2023 18:34:03 -0800 Subject: [PATCH 2/5] Bug fix: Do not fail when reading an extended attribute when the value contains an '=' character., --- .../src/System/Formats/Tar/TarHeader.Read.cs | 6 ------ 1 file changed, 6 deletions(-) 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); From 836abf9e62cebff48ade2dcea36ae96743213e5c Mon Sep 17 00:00:00 2001 From: carlossanlop Date: Tue, 28 Feb 2023 18:36:05 -0800 Subject: [PATCH 3/5] Add unit tests that verify extended attribute and global extended attribute roundtripping when the value contains an '=' character. Also add a null check for a subsequent GetNextEntry. --- .../TarReader/TarReader.File.GlobalExtendedAttributes.Tests.cs | 3 +++ .../System.Formats.Tar/tests/TarReader/TarReader.Tests.cs | 3 +++ 2 files changed, 6 insertions(+) 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..49a6a22390fce 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 @@ -90,6 +90,8 @@ public void ExtractGlobalExtendedAttributesEntry_Throws() [InlineData(" key ", " value ")] [InlineData(" key spaced ", " value spaced ")] [InlineData("many sla/s\\hes", "/////////////\\\\\\///////////")] + [InlineData("key", "va=lue")] + [InlineData("key", "=")] public void GlobalExtendedAttribute_Roundtrips(string key, string value) { var stream = new MemoryStream(); @@ -104,6 +106,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.Tests.cs b/src/libraries/System.Formats.Tar/tests/TarReader/TarReader.Tests.cs index d232441608c05..daaeeef82ab95 100644 --- a/src/libraries/System.Formats.Tar/tests/TarReader/TarReader.Tests.cs +++ b/src/libraries/System.Formats.Tar/tests/TarReader/TarReader.Tests.cs @@ -106,6 +106,8 @@ public void TarReader_LeaveOpen_False_CopiedDataNotDisposed() [InlineData(" key ", " value ")] [InlineData(" key spaced ", " value spaced ")] [InlineData("many sla/s\\hes", "/////////////\\\\\\///////////")] + [InlineData("key", "va=lue")] + [InlineData("key", "=")] public void PaxExtendedAttribute_Roundtrips(string key, string value) { var stream = new MemoryStream(); @@ -120,6 +122,7 @@ public void PaxExtendedAttribute_Roundtrips(string key, string value) PaxTarEntry entry = Assert.IsType(reader.GetNextEntry()); Assert.Equal(5, entry.ExtendedAttributes.Count); Assert.Contains(KeyValuePair.Create(key, value), entry.ExtendedAttributes); + Assert.Null(reader.GetNextEntry()); } } } From 4475f15dd7df88aab6974a62408599c3ecdd2365 Mon Sep 17 00:00:00 2001 From: carlossanlop Date: Tue, 28 Feb 2023 18:52:20 -0800 Subject: [PATCH 4/5] Convert duplicate InlineData to single shared MemberData method. --- .../TarReader.File.GlobalExtendedAttributes.Tests.cs | 9 +-------- .../tests/TarReader/TarReader.Tests.cs | 9 +-------- .../System.Formats.Tar/tests/TarTestsBase.Pax.cs | 12 ++++++++++++ 3 files changed, 14 insertions(+), 16 deletions(-) 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 49a6a22390fce..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,14 +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", "/////////////\\\\\\///////////")] - [InlineData("key", "va=lue")] - [InlineData("key", "=")] + [MemberData(nameof(GetPaxExtendedAttributesRoundtripTestData))] public void GlobalExtendedAttribute_Roundtrips(string key, string value) { var stream = new MemoryStream(); 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 daaeeef82ab95..f95a22335a141 100644 --- a/src/libraries/System.Formats.Tar/tests/TarReader/TarReader.Tests.cs +++ b/src/libraries/System.Formats.Tar/tests/TarReader/TarReader.Tests.cs @@ -100,14 +100,7 @@ public void TarReader_LeaveOpen_False_CopiedDataNotDisposed() } [Theory] - [InlineData("key", "value")] - [InlineData("key ", "value ")] - [InlineData(" key", " value")] - [InlineData(" key ", " value ")] - [InlineData(" key spaced ", " value spaced ")] - [InlineData("many sla/s\\hes", "/////////////\\\\\\///////////")] - [InlineData("key", "va=lue")] - [InlineData("key", "=")] + [MemberData(nameof(GetPaxExtendedAttributesRoundtripTestData))] public void PaxExtendedAttribute_Roundtrips(string key, string value) { var stream = new MemoryStream(); diff --git a/src/libraries/System.Formats.Tar/tests/TarTestsBase.Pax.cs b/src/libraries/System.Formats.Tar/tests/TarTestsBase.Pax.cs index dd71b15796396..d85b1ee3db8d3 100644 --- a/src/libraries/System.Formats.Tar/tests/TarTestsBase.Pax.cs +++ b/src/libraries/System.Formats.Tar/tests/TarTestsBase.Pax.cs @@ -124,5 +124,17 @@ 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", "va=lue" }; + yield return new object[] { "key", "=" }; + } } } From d4ca87854565771bd6dc562fadcfa237aa62f92a Mon Sep 17 00:00:00 2001 From: carlossanlop <1175054+carlossanlop@users.noreply.github.com> Date: Thu, 2 Mar 2023 21:11:48 -0800 Subject: [PATCH 5/5] Apply suggestion --- src/libraries/System.Formats.Tar/tests/TarTestsBase.Pax.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Formats.Tar/tests/TarTestsBase.Pax.cs b/src/libraries/System.Formats.Tar/tests/TarTestsBase.Pax.cs index d85b1ee3db8d3..c1776753512cf 100644 --- a/src/libraries/System.Formats.Tar/tests/TarTestsBase.Pax.cs +++ b/src/libraries/System.Formats.Tar/tests/TarTestsBase.Pax.cs @@ -133,8 +133,12 @@ public static IEnumerable GetPaxExtendedAttributesRoundtripTestData() 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", "va=lue" }; 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==" }; } } }