Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
44300eb
Throw ArgumentException on unsupported tar entry type
carlossanlop Aug 30, 2022
386ca70
Adjust tests
carlossanlop Aug 30, 2022
4c049be
Also change exception type for internal TarEntry conversion construct…
carlossanlop Aug 30, 2022
712acb5
LinkName setter null check.
carlossanlop Aug 31, 2022
785584d
Internal constructors SeekableSubReadStream and SubReadStream unseeka…
carlossanlop Aug 31, 2022
5931c6b
DataStream setter for regular file should throw ArgumentException if …
carlossanlop Aug 31, 2022
2848e80
TarFile CreateFromDirectory unwritable destination change exception t…
carlossanlop Aug 31, 2022
1647a89
Change to ArgumentException when ExtractToDirectory is an unreadable …
carlossanlop Aug 31, 2022
5216a08
Add some missing exception docs for TarEntry.
carlossanlop Aug 31, 2022
64efec2
Change TarReader constructor exception if unreadable stream. Close te…
carlossanlop Aug 31, 2022
3694af2
Change TarWriter exception for unwritable stream to ArgumentException…
carlossanlop Aug 31, 2022
bc608fc
Add missing documentation for exceptions in constructors.
carlossanlop Aug 31, 2022
b6d620c
Change wording of conversion constructors comment when passing a Pax …
carlossanlop Aug 31, 2022
9c4ccaa
Apply suggestions by Jozkee
carlossanlop Aug 31, 2022
13f52c0
Add exception to LinkName if the entry type is hard/symlink and the u…
carlossanlop Aug 31, 2022
e7d911d
Convert all FormatException to InvalidDataException
carlossanlop Aug 31, 2022
ed4ab9c
Address more suggestions
carlossanlop Aug 31, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Change to ArgumentException when ExtractToDirectory is an unreadable …
…stream. Add missing exception docs.
  • Loading branch information
carlossanlop committed Aug 31, 2022
commit 1647a89834d562f45ad49332ecad29cf4a7ae263
54 changes: 50 additions & 4 deletions src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ public static class TarFile
/// <param name="sourceDirectoryName">The path of the directory to archive.</param>
/// <param name="destination">The destination stream the archive.</param>
/// <param name="includeBaseDirectory"><see langword="true"/> to include the base directory name as the first segment in all the names of the archive entries. <see langword="false"/> to exclude the base directory name from the archive entry names.</param>
/// <exception cref="ArgumentNullException"><paramref name="sourceDirectoryName"/> of <paramref name="destination"/> is <see langword="null"/>.</exception>
/// <exception cref="ArgumentException"><para><paramref name="sourceDirectoryName"/> is empty.</para>
/// <para>-or-</para>
/// <para><paramref name="destination"/> is an unwritable stream.</para></exception>
/// <exception cref="DirectoryNotFoundException">The <paramref name="sourceDirectoryName"/> directory path was not found.</exception>
/// <exception cref="IOException">An I/O exception occurred.</exception>
public static void CreateFromDirectory(string sourceDirectoryName, Stream destination, bool includeBaseDirectory)
{
ArgumentException.ThrowIfNullOrEmpty(sourceDirectoryName);
Expand Down Expand Up @@ -50,7 +56,12 @@ public static void CreateFromDirectory(string sourceDirectoryName, Stream destin
/// <param name="destination">The destination stream of the archive.</param>
/// <param name="includeBaseDirectory"><see langword="true"/> to include the base directory name as the first path segment in all the names of the archive entries. <see langword="false"/> to exclude the base directory name from the entry name paths.</param>
/// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
/// <returns>A task that represents the asynchronous creation operation.</returns>
/// <returns>A task that represents the asynchronous creation operation.</returns>\/// <exception cref="ArgumentNullException"><paramref name="sourceDirectoryName"/> of <paramref name="destination"/> is <see langword="null"/>.</exception>
/// <exception cref="ArgumentException"><para><paramref name="sourceDirectoryName"/> is empty.</para>
/// <para>-or-</para>
/// <para><paramref name="destination"/> is an unwritable stream.</para></exception>
/// <exception cref="DirectoryNotFoundException">The <paramref name="sourceDirectoryName"/> directory path was not found.</exception>
/// <exception cref="IOException">An I/O exception occurred.</exception>
public static Task CreateFromDirectoryAsync(string sourceDirectoryName, Stream destination, bool includeBaseDirectory, CancellationToken cancellationToken = default)
{
if (cancellationToken.IsCancellationRequested)
Expand Down Expand Up @@ -82,6 +93,10 @@ public static Task CreateFromDirectoryAsync(string sourceDirectoryName, Stream d
/// <param name="sourceDirectoryName">The path of the directory to archive.</param>
/// <param name="destinationFileName">The path of the destination archive file.</param>
/// <param name="includeBaseDirectory"><see langword="true"/> to include the base directory name as the first path segment in all the names of the archive entries. <see langword="false"/> to exclude the base directory name from the entry name paths.</param>
/// <exception cref="ArgumentNullException"><paramref name="sourceDirectoryName"/> or <paramref name="destinationFileName"/> is <see langword="null"/>.</exception>
/// <exception cref="ArgumentException"><paramref name="sourceDirectoryName"/> or <paramref name="destinationFileName"/> is empty.</exception>
/// <exception cref="DirectoryNotFoundException">The <paramref name="sourceDirectoryName"/> directory path was not found.</exception>
/// <exception cref="IOException">An I/O exception occurred.</exception>
public static void CreateFromDirectory(string sourceDirectoryName, string destinationFileName, bool includeBaseDirectory)
{
ArgumentException.ThrowIfNullOrEmpty(sourceDirectoryName);
Expand Down Expand Up @@ -110,6 +125,10 @@ public static void CreateFromDirectory(string sourceDirectoryName, string destin
/// <param name="includeBaseDirectory"><see langword="true"/> to include the base directory name as the first path segment in all the names of the archive entries. <see langword="false"/> to exclude the base directory name from the entry name paths.</param>
/// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None" />.</param>
/// <returns>A task that represents the asynchronous creation operation.</returns>
/// <exception cref="ArgumentNullException"><paramref name="sourceDirectoryName"/> or <paramref name="destinationFileName"/> is <see langword="null"/>.</exception>
/// <exception cref="ArgumentException"><paramref name="sourceDirectoryName"/> or <paramref name="destinationFileName"/> is empty.</exception>
/// <exception cref="DirectoryNotFoundException">The <paramref name="sourceDirectoryName"/> directory path was not found.</exception>
/// <exception cref="IOException">An I/O exception occurred.</exception>
public static Task CreateFromDirectoryAsync(string sourceDirectoryName, string destinationFileName, bool includeBaseDirectory, CancellationToken cancellationToken = default)
{
if (cancellationToken.IsCancellationRequested)
Expand Down Expand Up @@ -139,16 +158,21 @@ public static Task CreateFromDirectoryAsync(string sourceDirectoryName, string d
/// <param name="overwriteFiles"><see langword="true"/> to overwrite files and directories in <paramref name="destinationDirectoryName"/>; <see langword="false"/> to avoid overwriting, and throw if any files or directories are found with existing names.</param>
/// <remarks><para>Files of type <see cref="TarEntryType.BlockDevice"/>, <see cref="TarEntryType.CharacterDevice"/> or <see cref="TarEntryType.Fifo"/> can only be extracted in Unix platforms.</para>
/// <para>Elevation is required to extract a <see cref="TarEntryType.BlockDevice"/> or <see cref="TarEntryType.CharacterDevice"/> to disk.</para></remarks>
/// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="destinationDirectoryName"/> is <see langword="null"/>.</exception>
/// <exception cref="DirectoryNotFoundException">The <paramref name="destinationDirectoryName"/> directory path was not found.</exception>
/// <exception cref="UnauthorizedAccessException">Operation not permitted due to insufficient permissions.</exception>
/// <exception cref="IOException">Extracting tar entry would have resulted in a file outside the specified destination directory.</exception>
/// <exception cref="ArgumentException"><para>Extracting tar entry would have resulted in a file outside the specified destination directory.</para>
/// <para>-or-</para>
/// <para><paramref name="destinationDirectoryName"/> is empty.</para></exception>
/// <exception cref="IOException">An I/O exception occurred.</exception>
public static void ExtractToDirectory(Stream source, string destinationDirectoryName, bool overwriteFiles)
{
ArgumentNullException.ThrowIfNull(source);
ArgumentException.ThrowIfNullOrEmpty(destinationDirectoryName);

if (!source.CanRead)
{
throw new IOException(SR.IO_NotSupported_UnreadableStream);
throw new ArgumentException(SR.IO_NotSupported_UnreadableStream, nameof(source));
}

if (!Directory.Exists(destinationDirectoryName))
Expand All @@ -172,7 +196,15 @@ public static void ExtractToDirectory(Stream source, string destinationDirectory
/// <returns>A task that represents the asynchronous extraction operation.</returns>
/// <remarks><para>Files of type <see cref="TarEntryType.BlockDevice"/>, <see cref="TarEntryType.CharacterDevice"/> or <see cref="TarEntryType.Fifo"/> can only be extracted in Unix platforms.</para>
/// <para>Elevation is required to extract a <see cref="TarEntryType.BlockDevice"/> or <see cref="TarEntryType.CharacterDevice"/> to disk.</para></remarks>
/// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="destinationDirectoryName"/> is <see langword="null"/>.</exception>
/// <exception cref="DirectoryNotFoundException">The <paramref name="destinationDirectoryName"/> directory path was not found.</exception>
/// <exception cref="UnauthorizedAccessException">Operation not permitted due to insufficient permissions.</exception>
/// <exception cref="ArgumentException"><para>Extracting tar entry would have resulted in a file outside the specified destination directory.</para>
/// <para>-or-</para>
/// <para><paramref name="destinationDirectoryName"/> is empty.</para>
/// <para>-or-</para>
/// <para><paramref name="source"/> is an unreadable stream.</para></exception>
/// <exception cref="IOException">An I/O exception occurred.</exception>
public static Task ExtractToDirectoryAsync(Stream source, string destinationDirectoryName, bool overwriteFiles, CancellationToken cancellationToken = default)
{
if (cancellationToken.IsCancellationRequested)
Expand All @@ -184,7 +216,7 @@ public static Task ExtractToDirectoryAsync(Stream source, string destinationDire

if (!source.CanRead)
{
return Task.FromException(new IOException(SR.IO_NotSupported_UnreadableStream));
return Task.FromException(new ArgumentException(SR.IO_NotSupported_UnreadableStream, nameof(source)));
}

if (!Directory.Exists(destinationDirectoryName))
Expand All @@ -206,7 +238,14 @@ public static Task ExtractToDirectoryAsync(Stream source, string destinationDire
/// <param name="overwriteFiles"><see langword="true"/> to overwrite files and directories in <paramref name="destinationDirectoryName"/>; <see langword="false"/> to avoid overwriting, and throw if any files or directories are found with existing names.</param>
/// <remarks><para>Files of type <see cref="TarEntryType.BlockDevice"/>, <see cref="TarEntryType.CharacterDevice"/> or <see cref="TarEntryType.Fifo"/> can only be extracted in Unix platforms.</para>
/// <para>Elevation is required to extract a <see cref="TarEntryType.BlockDevice"/> or <see cref="TarEntryType.CharacterDevice"/> to disk.</para></remarks>
/// <exception cref="ArgumentNullException"><paramref name="sourceFileName"/> or <paramref name="destinationDirectoryName"/> is <see langword="null"/>.</exception>
/// <exception cref="DirectoryNotFoundException">The <paramref name="destinationDirectoryName"/> directory path was not found.</exception>
/// <exception cref="FileNotFoundException"> The <paramref name="sourceFileName"/> file path was not found.</exception>
/// <exception cref="UnauthorizedAccessException">Operation not permitted due to insufficient permissions.</exception>
/// <exception cref="ArgumentException"><para>Extracting tar entry would have resulted in a file outside the specified destination directory.</para>
/// <para>-or-</para>
/// <para><paramref name="sourceFileName"/> or <paramref name="destinationDirectoryName"/> is empty.</para></exception>
/// <exception cref="IOException">An I/O exception occurred.</exception>
public static void ExtractToDirectory(string sourceFileName, string destinationDirectoryName, bool overwriteFiles)
{
ArgumentException.ThrowIfNullOrEmpty(sourceFileName);
Expand Down Expand Up @@ -241,7 +280,14 @@ public static void ExtractToDirectory(string sourceFileName, string destinationD
/// <returns>A task that represents the asynchronous extraction operation.</returns>
/// <remarks><para>Files of type <see cref="TarEntryType.BlockDevice"/>, <see cref="TarEntryType.CharacterDevice"/> or <see cref="TarEntryType.Fifo"/> can only be extracted in Unix platforms.</para>
/// <para>Elevation is required to extract a <see cref="TarEntryType.BlockDevice"/> or <see cref="TarEntryType.CharacterDevice"/> to disk.</para></remarks>
/// <exception cref="ArgumentNullException"><paramref name="sourceFileName"/> or <paramref name="destinationDirectoryName"/> is <see langword="null"/>.</exception>
/// <exception cref="DirectoryNotFoundException">The <paramref name="destinationDirectoryName"/> directory path was not found.</exception>
/// <exception cref="FileNotFoundException"> The <paramref name="sourceFileName"/> file path was not found.</exception>
/// <exception cref="UnauthorizedAccessException">Operation not permitted due to insufficient permissions.</exception>
/// <exception cref="ArgumentException"><para>Extracting tar entry would have resulted in a file outside the specified destination directory.</para>
/// <para>-or-</para>
/// <para><paramref name="sourceFileName"/> or <paramref name="destinationDirectoryName"/> is empty.</para></exception>
/// <exception cref="IOException">An I/O exception occurred.</exception>
public static Task ExtractToDirectoryAsync(string sourceFileName, string destinationDirectoryName, bool overwriteFiles, CancellationToken cancellationToken = default)
{
if (cancellationToken.IsCancellationRequested)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public void UnreadableStream_Throws()
{
using MemoryStream archive = new MemoryStream();
using WrappedStream unreadable = new WrappedStream(archive, canRead: false, canWrite: true, canSeek: true);
Assert.Throws<IOException>(() => TarFile.ExtractToDirectory(unreadable, destinationDirectoryName: "path", overwriteFiles: false));
Assert.Throws<ArgumentException>(() => TarFile.ExtractToDirectory(unreadable, destinationDirectoryName: "path", overwriteFiles: false));
}

[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public async Task UnreadableStream_Throws_Async()
{
using (WrappedStream unreadable = new WrappedStream(archive, canRead: false, canWrite: true, canSeek: true))
{
await Assert.ThrowsAsync<IOException>(() => TarFile.ExtractToDirectoryAsync(unreadable, destinationDirectoryName: "path", overwriteFiles: false));
await Assert.ThrowsAsync<ArgumentException>(() => TarFile.ExtractToDirectoryAsync(unreadable, destinationDirectoryName: "path", overwriteFiles: false));
}
}
}
Expand Down