diff --git a/src/libraries/System.Formats.Tar/tests/TarEntry/TarEntry.Conversion.Tests.Base.cs b/src/libraries/System.Formats.Tar/tests/TarEntry/TarEntry.Conversion.Tests.Base.cs index 29fab86d2280e5..2a4a4fe28ca8d7 100644 --- a/src/libraries/System.Formats.Tar/tests/TarEntry/TarEntry.Conversion.Tests.Base.cs +++ b/src/libraries/System.Formats.Tar/tests/TarEntry/TarEntry.Conversion.Tests.Base.cs @@ -177,16 +177,6 @@ private void GetExpectedTimestampsFromOriginalPaxOrGnu(TarEntry originalEntry, o } - protected TarEntry InvokeTarEntryCreationConstructor(TarEntryFormat targetFormat, TarEntryType entryType, string entryName) - => targetFormat switch - { - TarEntryFormat.V7 => new V7TarEntry(entryType, entryName), - TarEntryFormat.Ustar => new UstarTarEntry(entryType, entryName), - TarEntryFormat.Pax => new PaxTarEntry(entryType, entryName), - TarEntryFormat.Gnu => new GnuTarEntry(entryType, entryName), - _ => throw new FormatException($"Unexpected format: {targetFormat}") - }; - protected TarEntry InvokeTarEntryConversionConstructor(TarEntryFormat targetFormat, TarEntry other) => targetFormat switch { diff --git a/src/libraries/System.Formats.Tar/tests/TarFile/TarFile.ExtractToDirectory.Stream.Tests.cs b/src/libraries/System.Formats.Tar/tests/TarFile/TarFile.ExtractToDirectory.Stream.Tests.cs index 9464e92488795e..5a68d5a95d5d26 100644 --- a/src/libraries/System.Formats.Tar/tests/TarFile/TarFile.ExtractToDirectory.Stream.Tests.cs +++ b/src/libraries/System.Formats.Tar/tests/TarFile/TarFile.ExtractToDirectory.Stream.Tests.cs @@ -94,35 +94,56 @@ public void Extract_LinkEntry_TargetOutsideDirectory(TarEntryType entryType) Assert.Equal(0, Directory.GetFileSystemEntries(root.Path).Count()); } - [ConditionalFact(typeof(MountHelper), nameof(MountHelper.CanCreateSymbolicLinks))] - public void Extract_SymbolicLinkEntry_TargetInsideDirectory() => Extract_LinkEntry_TargetInsideDirectory_Internal(TarEntryType.SymbolicLink); - - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.SupportsHardLinkCreation))] - public void Extract_HardLinkEntry_TargetInsideDirectory() => Extract_LinkEntry_TargetInsideDirectory_Internal(TarEntryType.HardLink); - - private void Extract_LinkEntry_TargetInsideDirectory_Internal(TarEntryType entryType) + [ConditionalTheory(typeof(MountHelper), nameof(MountHelper.CanCreateSymbolicLinks))] + [InlineData(TarEntryFormat.Pax)] + [InlineData(TarEntryFormat.Gnu)] + public void Extract_SymbolicLinkEntry_TargetInsideDirectory(TarEntryFormat format) => Extract_LinkEntry_TargetInsideDirectory_Internal(TarEntryType.SymbolicLink, format, null); + + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.SupportsHardLinkCreation))] + [InlineData(TarEntryFormat.Pax)] + [InlineData(TarEntryFormat.Gnu)] + public void Extract_HardLinkEntry_TargetInsideDirectory(TarEntryFormat format) => Extract_LinkEntry_TargetInsideDirectory_Internal(TarEntryType.HardLink, format, null); + + [ConditionalTheory(typeof(MountHelper), nameof(MountHelper.CanCreateSymbolicLinks))] + [InlineData(TarEntryFormat.Pax)] + [InlineData(TarEntryFormat.Gnu)] + public void Extract_SymbolicLinkEntry_TargetInsideDirectory_LongBaseDir(TarEntryFormat format) => Extract_LinkEntry_TargetInsideDirectory_Internal(TarEntryType.SymbolicLink, format, new string('a', 99)); + + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.SupportsHardLinkCreation))] + [InlineData(TarEntryFormat.Pax)] + [InlineData(TarEntryFormat.Gnu)] + public void Extract_HardLinkEntry_TargetInsideDirectory_LongBaseDir(TarEntryFormat format) => Extract_LinkEntry_TargetInsideDirectory_Internal(TarEntryType.HardLink, format, new string('a', 99)); + + // This test would not pass for the V7 and Ustar formats in some OSs like MacCatalyst, tvOSSimulator and OSX, because the TempDirectory gets created in + // a folder with a path longer than 100 bytes, and those tar formats have no way of handling pathnames and linknames longer than that length. + // The rest of the OSs create the TempDirectory in a path that does not surpass the 100 bytes, so the 'subfolder' parameter gives a chance to extend + // the base directory past that length, to ensure this scenario is tested everywhere. + private void Extract_LinkEntry_TargetInsideDirectory_Internal(TarEntryType entryType, TarEntryFormat format, string subfolder) { using TempDirectory root = new TempDirectory(); + string baseDir = string.IsNullOrEmpty(subfolder) ? root.Path : Path.Join(root.Path, subfolder); + Directory.CreateDirectory(baseDir); + string linkName = "link"; string targetName = "target"; - string targetPath = Path.Join(root.Path, targetName); + string targetPath = Path.Join(baseDir, targetName); File.Create(targetPath).Dispose(); using MemoryStream archive = new MemoryStream(); - using (TarWriter writer = new TarWriter(archive, TarEntryFormat.Ustar, leaveOpen: true)) + using (TarWriter writer = new TarWriter(archive, format, leaveOpen: true)) { - UstarTarEntry entry = new UstarTarEntry(entryType, linkName); + TarEntry entry= InvokeTarEntryCreationConstructor(format, entryType, linkName); entry.LinkName = targetPath; writer.WriteEntry(entry); } archive.Seek(0, SeekOrigin.Begin); - TarFile.ExtractToDirectory(archive, root.Path, overwriteFiles: false); + TarFile.ExtractToDirectory(archive, baseDir, overwriteFiles: false); - Assert.Equal(2, Directory.GetFileSystemEntries(root.Path).Count()); + Assert.Equal(2, Directory.GetFileSystemEntries(baseDir).Count()); } } } diff --git a/src/libraries/System.Formats.Tar/tests/TarTestsBase.cs b/src/libraries/System.Formats.Tar/tests/TarTestsBase.cs index bfda06ff05b08c..88d1433cd04895 100644 --- a/src/libraries/System.Formats.Tar/tests/TarTestsBase.cs +++ b/src/libraries/System.Formats.Tar/tests/TarTestsBase.cs @@ -323,5 +323,16 @@ protected Type GetTypeForFormat(TarEntryFormat expectedFormat) _ => throw new FormatException($"Unrecognized format: {expectedFormat}"), }; } + + protected TarEntry InvokeTarEntryCreationConstructor(TarEntryFormat targetFormat, TarEntryType entryType, string entryName) + => targetFormat switch + { + TarEntryFormat.V7 => new V7TarEntry(entryType, entryName), + TarEntryFormat.Ustar => new UstarTarEntry(entryType, entryName), + TarEntryFormat.Pax => new PaxTarEntry(entryType, entryName), + TarEntryFormat.Gnu => new GnuTarEntry(entryType, entryName), + _ => throw new FormatException($"Unexpected format: {targetFormat}") + }; + } }