diff --git a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/PaxGlobalExtendedAttributesTarEntry.cs b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/PaxGlobalExtendedAttributesTarEntry.cs
index 832996693624f1e7a01cea99dd888163d5b8b9cc..94ba60167f721277a04f97bc278127e57d0f74f4 100644
--- a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/PaxGlobalExtendedAttributesTarEntry.cs
+++ b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/PaxGlobalExtendedAttributesTarEntry.cs
@@ -3,7 +3,6 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
-using System.Diagnostics;
namespace System.Formats.Tar
{
@@ -26,7 +25,7 @@ internal PaxGlobalExtendedAttributesTarEntry(TarHeader header, TarReader readerO
/// An enumeration of string key-value pairs that represents the metadata to include as Global Extended Attributes.
/// is .
public PaxGlobalExtendedAttributesTarEntry(IEnumerable> globalExtendedAttributes)
- : base(TarEntryType.GlobalExtendedAttributes, TarHeader.GlobalHeadFormatPrefix, TarEntryFormat.Pax, isGea: true)
+ : base(TarEntryType.GlobalExtendedAttributes, nameof(PaxGlobalExtendedAttributesTarEntry), TarEntryFormat.Pax, isGea: true) // Name == name of type for lack of a better temporary name until the entry is written
{
ArgumentNullException.ThrowIfNull(globalExtendedAttributes);
_header.InitializeExtendedAttributesWithExisting(globalExtendedAttributes);
diff --git a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarHeader.Write.cs b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarHeader.Write.cs
index 884c2bf1bcaf907ca8819f925fcde800b8298fbd..40b0e330b314b4dd802dc2b562432f85a3a64c83 100644
--- a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarHeader.Write.cs
+++ b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarHeader.Write.cs
@@ -893,32 +893,22 @@ private string GenerateExtendedAttributeName()
}
// Gets the special name for the 'name' field in a global extended attribute entry.
- // Format: "%d/GlobalHead.%p/%n"
+ // Format: "%d/GlobalHead.%p.%n"
// - %d: The path of the $TMPDIR variable, if found. Otherwise, the value is '/tmp'.
// - %p: The current process ID.
- // - %n: The sequence number of the global extended header record of the archive, starting at 1. In our case, since we only generate one, the value is always 1.
+ // - %n: The sequence number of the global extended header record of the archive, starting at 1.
// If the path of $TMPDIR makes the final string too long to fit in the 'name' field,
// then the TMPDIR='/tmp' is used.
private static string GenerateGlobalExtendedAttributeName(int globalExtendedAttributesEntryNumber)
{
Debug.Assert(globalExtendedAttributesEntryNumber >= 1);
- string tmpDir = Path.GetTempPath();
- if (Path.EndsInDirectorySeparator(tmpDir))
- {
- tmpDir = Path.TrimEndingDirectorySeparator(tmpDir);
- }
- int processId = Environment.ProcessId;
-
- string result = string.Format(GlobalHeadFormatPrefix, tmpDir, processId);
- string suffix = $".{globalExtendedAttributesEntryNumber}"; // GEA sequence number
- if (result.Length + suffix.Length >= FieldLengths.Name)
- {
- result = string.Format(GlobalHeadFormatPrefix, "/tmp", processId);
- }
- result += suffix;
+ ReadOnlySpan tmp = Path.TrimEndingDirectorySeparator(Path.GetTempPath());
- return result;
+ string result = $"{tmp}/GlobalHead.{Environment.ProcessId}.{globalExtendedAttributesEntryNumber}";
+ return result.Length >= FieldLengths.Name ?
+ string.Concat("/tmp", result.AsSpan(tmp.Length)) :
+ result;
}
private static int GetUtf8TextLength(ReadOnlySpan text)
diff --git a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarHeader.cs b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarHeader.cs
index 65fdda022b32b6cc31ec1eabf6a1146b54856d13..9510746a5cab159fb3f53d39aba445cf3cbfcd54 100644
--- a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarHeader.cs
+++ b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarHeader.cs
@@ -39,11 +39,6 @@ internal sealed partial class TarHeader
private const string PaxEaDevMajor = "devmajor";
private const string PaxEaDevMinor = "devminor";
- // Global Extended Attribute entries have a special format in the Name field:
- // "{tmpFolder}/GlobalHead.{processId}.{GEAEntryNumber}"
- // Excludes ".{GEAEntryNumber}" because the number gets added on write.
- internal const string GlobalHeadFormatPrefix = "{0}/GlobalHead.{1}";
-
internal Stream? _dataStream;
// Position in the stream where the data ends in this header.
diff --git a/src/libraries/System.Formats.Tar/tests/TarWriter/TarWriter.WriteEntryAsync.Entry.Pax.Tests.cs b/src/libraries/System.Formats.Tar/tests/TarWriter/TarWriter.WriteEntryAsync.Entry.Pax.Tests.cs
index b0c9d636420b5250d16605219278a6073f8dd7e6..fc6445a3b3e97140da40ddc6340ab5958910eb03 100644
--- a/src/libraries/System.Formats.Tar/tests/TarWriter/TarWriter.WriteEntryAsync.Entry.Pax.Tests.cs
+++ b/src/libraries/System.Formats.Tar/tests/TarWriter/TarWriter.WriteEntryAsync.Entry.Pax.Tests.cs
@@ -378,7 +378,9 @@ public async Task Add_Empty_GlobalExtendedAttributes_Async()
await using (TarWriter writer = new TarWriter(archive, leaveOpen: true))
{
PaxGlobalExtendedAttributesTarEntry gea = new PaxGlobalExtendedAttributesTarEntry(new Dictionary());
+ Assert.Equal("PaxGlobalExtendedAttributesTarEntry", gea.Name);
await writer.WriteEntryAsync(gea);
+ Assert.Matches(@".*/GlobalHead\.\d+\.\d+", gea.Name);
}
archive.Seek(0, SeekOrigin.Begin);