diff --git a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarFile.cs b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarFile.cs
index 978eb75cc6048e..51e3ad13e5b4c7 100644
--- a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarFile.cs
+++ b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarFile.cs
@@ -263,12 +263,12 @@ public static Task CreateFromDirectoryAsync(string sourceDirectoryName, string d
/// Extracts the contents of a stream that represents a tar archive into the specified directory.
///
/// The stream containing the tar archive.
- /// The path of the destination directory where the filesystem entries should be extracted.
- /// to overwrite files and directories in ; to avoid overwriting, and throw if any files or directories are found with existing names.
+ /// The path of the destination directory where the filesystem entries should be extracted.
+ /// Missing destination and parent directories are created as needed when entries are extracted. An empty archive does not create any directories.
+ /// to overwrite existing files in ; otherwise, to throw if a file to extract already exists.
/// Files of type , or can only be extracted in Unix platforms.
/// Elevation is required to extract a or to disk.
/// or is .
- /// The directory path was not found.
/// Operation not permitted due to insufficient permissions.
/// Extracting tar entry would have resulted in a file outside the specified destination directory.
/// -or-
@@ -283,12 +283,12 @@ public static void ExtractToDirectory(Stream source, string destinationDirectory
/// Extracts the contents of a stream that represents a tar archive into the specified directory.
///
/// The stream containing the tar archive.
- /// The path of the destination directory where the filesystem entries should be extracted.
+ /// The path of the destination directory where the filesystem entries should be extracted.
+ /// Missing destination and parent directories are created as needed when entries are extracted. An empty archive does not create any directories.
/// The options that configure the behavior of the extraction.
/// Files of type , or can only be extracted in Unix platforms.
/// Elevation is required to extract a or to disk.
/// , , or is .
- /// The directory path was not found.
/// Operation not permitted due to insufficient permissions.
/// Extracting tar entry would have resulted in a file outside the specified destination directory.
/// -or-
@@ -307,11 +307,6 @@ public static void ExtractToDirectory(Stream source, string destinationDirectory
throw new ArgumentException(SR.IO_NotSupported_UnreadableStream, nameof(source));
}
- if (!Directory.Exists(destinationDirectoryName))
- {
- throw new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, destinationDirectoryName), destinationDirectoryName);
- }
-
// Rely on Path.GetFullPath for validation of paths
destinationDirectoryName = Path.GetFullPath(destinationDirectoryName);
destinationDirectoryName = PathInternal.EnsureTrailingSeparator(destinationDirectoryName);
@@ -323,14 +318,14 @@ public static void ExtractToDirectory(Stream source, string destinationDirectory
/// Asynchronously extracts the contents of a stream that represents a tar archive into the specified directory.
///
/// The stream containing the tar archive.
- /// The path of the destination directory where the filesystem entries should be extracted.
- /// to overwrite files and directories in ; to avoid overwriting, and throw if any files or directories are found with existing names.
+ /// The path of the destination directory where the filesystem entries should be extracted.
+ /// Missing destination and parent directories are created as needed when entries are extracted. An empty archive does not create any directories.
+ /// to overwrite existing files in ; otherwise, to throw if a file to extract already exists.
/// The token to monitor for cancellation requests. The default value is .
/// A task that represents the asynchronous extraction operation.
/// Files of type , or can only be extracted in Unix platforms.
/// Elevation is required to extract a or to disk.
/// or is .
- /// The directory path was not found.
/// Operation not permitted due to insufficient permissions.
/// Extracting tar entry would have resulted in a file outside the specified destination directory.
/// -or-
@@ -345,14 +340,14 @@ public static Task ExtractToDirectoryAsync(Stream source, string destinationDire
/// Asynchronously extracts the contents of a stream that represents a tar archive into the specified directory.
///
/// The stream containing the tar archive.
- /// The path of the destination directory where the filesystem entries should be extracted.
+ /// The path of the destination directory where the filesystem entries should be extracted.
+ /// Missing destination and parent directories are created as needed when entries are extracted. An empty archive does not create any directories.
/// The options that configure the behavior of the extraction.
/// The token to monitor for cancellation requests. The default value is .
/// A task that represents the asynchronous extraction operation.
/// Files of type , or can only be extracted in Unix platforms.
/// Elevation is required to extract a or to disk.
/// , , or is .
- /// The directory path was not found.
/// Operation not permitted due to insufficient permissions.
/// Extracting tar entry would have resulted in a file outside the specified destination directory.
/// -or-
@@ -375,11 +370,6 @@ public static Task ExtractToDirectoryAsync(Stream source, string destinationDire
return Task.FromException(new ArgumentException(SR.IO_NotSupported_UnreadableStream, nameof(source)));
}
- if (!Directory.Exists(destinationDirectoryName))
- {
- return Task.FromException(new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, destinationDirectoryName), destinationDirectoryName));
- }
-
// Rely on Path.GetFullPath for validation of paths
destinationDirectoryName = Path.GetFullPath(destinationDirectoryName);
destinationDirectoryName = PathInternal.EnsureTrailingSeparator(destinationDirectoryName);
@@ -391,12 +381,12 @@ public static Task ExtractToDirectoryAsync(Stream source, string destinationDire
/// Extracts the contents of a tar file into the specified directory.
///
/// The path of the tar file to extract.
- /// The path of the destination directory where the filesystem entries should be extracted.
- /// to overwrite files and directories in ; to avoid overwriting, and throw if any files or directories are found with existing names.
+ /// The path of the destination directory where the filesystem entries should be extracted.
+ /// Missing destination and parent directories are created as needed when entries are extracted. An empty archive does not create any directories.
+ /// to overwrite existing files in ; otherwise, to throw if a file to extract already exists.
/// Files of type , or can only be extracted in Unix platforms.
/// Elevation is required to extract a or to disk.
/// or is .
- /// The directory path was not found.
/// The file path was not found.
/// Operation not permitted due to insufficient permissions.
/// Extracting tar entry would have resulted in a file outside the specified destination directory.
@@ -410,12 +400,12 @@ public static void ExtractToDirectory(string sourceFileName, string destinationD
/// Extracts the contents of a tar file into the specified directory.
///
/// The path of the tar file to extract.
- /// The path of the destination directory where the filesystem entries should be extracted.
+ /// The path of the destination directory where the filesystem entries should be extracted.
+ /// Missing destination and parent directories are created as needed when entries are extracted. An empty archive does not create any directories.
/// The options that configure the behavior of the extraction.
/// Files of type , or can only be extracted in Unix platforms.
/// Elevation is required to extract a or to disk.
/// , , or is .
- /// The directory path was not found.
/// The file path was not found.
/// Operation not permitted due to insufficient permissions.
/// Extracting tar entry would have resulted in a file outside the specified destination directory.
@@ -438,11 +428,6 @@ public static void ExtractToDirectory(string sourceFileName, string destinationD
throw new FileNotFoundException(SR.Format(SR.IO_FileNotFound_FileName, sourceFileName));
}
- if (!Directory.Exists(destinationDirectoryName))
- {
- throw new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, destinationDirectoryName), destinationDirectoryName);
- }
-
using FileStream archive = File.OpenRead(sourceFileName);
ExtractToDirectoryInternal(archive, destinationDirectoryName, options, leaveOpen: false);
@@ -452,14 +437,14 @@ public static void ExtractToDirectory(string sourceFileName, string destinationD
/// Asynchronously extracts the contents of a tar file into the specified directory.
///
/// The path of the tar file to extract.
- /// The path of the destination directory where the filesystem entries should be extracted.
- /// to overwrite files and directories in ; to avoid overwriting, and throw if any files or directories are found with existing names.
+ /// The path of the destination directory where the filesystem entries should be extracted.
+ /// Missing destination and parent directories are created as needed when entries are extracted. An empty archive does not create any directories.
+ /// to overwrite existing files in ; otherwise, to throw if a file to extract already exists.
/// The token to monitor for cancellation requests. The default value is .
/// A task that represents the asynchronous extraction operation.
/// Files of type , or can only be extracted in Unix platforms.
/// Elevation is required to extract a or to disk.
/// or is .
- /// The directory path was not found.
/// The file path was not found.
/// Operation not permitted due to insufficient permissions.
/// Extracting tar entry would have resulted in a file outside the specified destination directory.
@@ -473,14 +458,14 @@ public static Task ExtractToDirectoryAsync(string sourceFileName, string destina
/// Asynchronously extracts the contents of a tar file into the specified directory.
///
/// The path of the tar file to extract.
- /// The path of the destination directory where the filesystem entries should be extracted.
+ /// The path of the destination directory where the filesystem entries should be extracted.
+ /// Missing destination and parent directories are created as needed when entries are extracted. An empty archive does not create any directories.
/// The options that configure the behavior of the extraction.
/// The token to monitor for cancellation requests. The default value is .
/// A task that represents the asynchronous extraction operation.
/// Files of type , or can only be extracted in Unix platforms.
/// Elevation is required to extract a or to disk.
/// , , or is .
- /// The directory path was not found.
/// The file path was not found.
/// Operation not permitted due to insufficient permissions.
/// Extracting tar entry would have resulted in a file outside the specified destination directory.
@@ -507,11 +492,6 @@ public static Task ExtractToDirectoryAsync(string sourceFileName, string destina
return Task.FromException(new FileNotFoundException(SR.Format(SR.IO_FileNotFound_FileName, sourceFileName)));
}
- if (!Directory.Exists(destinationDirectoryName))
- {
- return Task.FromException(new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, destinationDirectoryName), destinationDirectoryName));
- }
-
return ExtractToDirectoryInternalAsync(sourceFileName, destinationDirectoryName, options, cancellationToken);
}
diff --git a/src/libraries/System.Formats.Tar/tests/TarFile/TarFile.ExtractToDirectory.Base.cs b/src/libraries/System.Formats.Tar/tests/TarFile/TarFile.ExtractToDirectory.Base.cs
index b5a1f111aa6a46..73627a737dcad1 100644
--- a/src/libraries/System.Formats.Tar/tests/TarFile/TarFile.ExtractToDirectory.Base.cs
+++ b/src/libraries/System.Formats.Tar/tests/TarFile/TarFile.ExtractToDirectory.Base.cs
@@ -2,11 +2,183 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Xunit;
namespace System.Formats.Tar.Tests;
public abstract class TarFile_ExtractToDirectory_Tests : TarTestsBase
{
+ protected abstract Task ExtractArchive(MemoryStream archive, string destinationDirectoryName, bool overwriteFiles, bool useOptions, bool async, CancellationToken cancellationToken = default);
+
+ public static IEnumerable