Skip to content

Commit 05b1a93

Browse files
committed
Merge in 'release/7.0' changes
2 parents 7a98e3f + 64ddf49 commit 05b1a93

File tree

5 files changed

+103
-7
lines changed

5 files changed

+103
-7
lines changed

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

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -723,13 +723,7 @@ private static bool TryGetNextExtendedAttribute(
723723
{
724724
return false;
725725
}
726-
line = line.Slice(spacePos + 1).TrimStart((byte)' ');
727-
728-
// If there are any more spaces, it's malformed.
729-
if (line.IndexOf((byte)' ') >= 0)
730-
{
731-
return false;
732-
}
726+
line = line.Slice(spacePos + 1);
733727

734728
// Find the equal separator.
735729
int equalPos = line.IndexOf((byte)'=');

src/libraries/System.Formats.Tar/tests/TarFile/TarFile.ExtractToDirectory.Stream.Tests.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,5 +177,32 @@ public void Extract_UnseekableStream_BlockAlignmentPadding_DoesNotAffectNextEntr
177177

178178
Assert.Equal(2, Directory.GetFileSystemEntries(destination.Path, "*", SearchOption.AllDirectories).Count());
179179
}
180+
181+
[Fact]
182+
public void PaxNameCollision_DedupInExtendedAttributes()
183+
{
184+
using TempDirectory root = new();
185+
186+
string sharedRootFolders = Path.Join(root.Path, "folder with spaces", new string('a', 100));
187+
string path1 = Path.Join(sharedRootFolders, "entry 1 with spaces.txt");
188+
string path2 = Path.Join(sharedRootFolders, "entry 2 with spaces.txt");
189+
190+
using MemoryStream stream = new();
191+
using (TarWriter writer = new(stream, TarEntryFormat.Pax, leaveOpen: true))
192+
{
193+
// Paths don't fit in the standard 'name' field, but they differ in the filename,
194+
// which is fully stored as an extended attribute
195+
PaxTarEntry entry1 = new(TarEntryType.RegularFile, path1);
196+
writer.WriteEntry(entry1);
197+
PaxTarEntry entry2 = new(TarEntryType.RegularFile, path2);
198+
writer.WriteEntry(entry2);
199+
}
200+
stream.Position = 0;
201+
202+
TarFile.ExtractToDirectory(stream, root.Path, overwriteFiles: true);
203+
204+
Assert.True(File.Exists(path1));
205+
Assert.True(Path.Exists(path2));
206+
}
180207
}
181208
}

src/libraries/System.Formats.Tar/tests/TarFile/TarFile.ExtractToDirectoryAsync.Stream.Tests.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,5 +242,32 @@ public async Task Extract_UnseekableStream_BlockAlignmentPadding_DoesNotAffectNe
242242

243243
Assert.Equal(2, Directory.GetFileSystemEntries(destination.Path, "*", SearchOption.AllDirectories).Count());
244244
}
245+
246+
[Fact]
247+
public async Task PaxNameCollision_DedupInExtendedAttributesAsync()
248+
{
249+
using TempDirectory root = new();
250+
251+
string sharedRootFolders = Path.Join(root.Path, "folder with spaces", new string('a', 100));
252+
string path1 = Path.Join(sharedRootFolders, "entry 1 with spaces.txt");
253+
string path2 = Path.Join(sharedRootFolders, "entry 2 with spaces.txt");
254+
255+
await using MemoryStream stream = new();
256+
await using (TarWriter writer = new(stream, TarEntryFormat.Pax, leaveOpen: true))
257+
{
258+
// Paths don't fit in the standard 'name' field, but they differ in the filename,
259+
// which is fully stored as an extended attribute
260+
PaxTarEntry entry1 = new(TarEntryType.RegularFile, path1);
261+
await writer.WriteEntryAsync(entry1);
262+
PaxTarEntry entry2 = new(TarEntryType.RegularFile, path2);
263+
await writer.WriteEntryAsync(entry2);
264+
}
265+
stream.Position = 0;
266+
267+
await TarFile.ExtractToDirectoryAsync(stream, root.Path, overwriteFiles: true);
268+
269+
Assert.True(File.Exists(path1));
270+
Assert.True(Path.Exists(path2));
271+
}
245272
}
246273
}

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,5 +82,29 @@ public void ExtractGlobalExtendedAttributesEntry_Throws()
8282
Assert.Throws<InvalidOperationException>(() => entry.ExtractToFile(Path.Join(root.Path, "file"), overwrite: true));
8383
}
8484
}
85+
86+
[Theory]
87+
[InlineData("key", "value")]
88+
[InlineData("key ", "value ")]
89+
[InlineData(" key", " value")]
90+
[InlineData(" key ", " value ")]
91+
[InlineData(" key spaced ", " value spaced ")]
92+
[InlineData("many sla/s\\hes", "/////////////\\\\\\///////////")]
93+
public void GlobalExtendedAttribute_Roundtrips(string key, string value)
94+
{
95+
var stream = new MemoryStream();
96+
using (var writer = new TarWriter(stream, leaveOpen: true))
97+
{
98+
writer.WriteEntry(new PaxGlobalExtendedAttributesTarEntry(new Dictionary<string, string>() { { key, value } }));
99+
}
100+
101+
stream.Position = 0;
102+
using (var reader = new TarReader(stream))
103+
{
104+
PaxGlobalExtendedAttributesTarEntry entry = Assert.IsType<PaxGlobalExtendedAttributesTarEntry>(reader.GetNextEntry());
105+
Assert.Equal(1, entry.GlobalExtendedAttributes.Count);
106+
Assert.Equal(KeyValuePair.Create(key, value), entry.GlobalExtendedAttributes.First());
107+
}
108+
}
85109
}
86110
}

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,30 @@ public void PaxSizeLargerThanMaxAllowedByStream()
325325
Assert.Throws<ArgumentOutOfRangeException>(() => reader.GetNextEntry());
326326
}
327327

328+
[Theory]
329+
[InlineData("key", "value")]
330+
[InlineData("key ", "value ")]
331+
[InlineData(" key", " value")]
332+
[InlineData(" key ", " value ")]
333+
[InlineData(" key spaced ", " value spaced ")]
334+
[InlineData("many sla/s\\hes", "/////////////\\\\\\///////////")]
335+
public void PaxExtendedAttribute_Roundtrips(string key, string value)
336+
{
337+
var stream = new MemoryStream();
338+
using (var writer = new TarWriter(stream, leaveOpen: true))
339+
{
340+
writer.WriteEntry(new PaxTarEntry(TarEntryType.Directory, "entryName", new Dictionary<string, string>() { { key, value } }));
341+
}
342+
343+
stream.Position = 0;
344+
using (var reader = new TarReader(stream))
345+
{
346+
PaxTarEntry entry = Assert.IsType<PaxTarEntry>(reader.GetNextEntry());
347+
Assert.Equal(5, entry.ExtendedAttributes.Count);
348+
Assert.Contains(KeyValuePair.Create(key, value), entry.ExtendedAttributes);
349+
}
350+
}
351+
328352
private static void VerifyDataStreamOfTarUncompressedInternal(string testFolderName, string testCaseName, bool copyData)
329353
{
330354
using MemoryStream archiveStream = GetTarMemoryStream(CompressionMethod.Uncompressed, testFolderName, testCaseName);

0 commit comments

Comments
 (0)