Skip to content

Commit

Permalink
Throw DirectoryNotFoundException on Image.Save with bad directory (#3…
Browse files Browse the repository at this point in the history
…4998)

* Provide better exception when saving to non-existent directory

When saving an image to a non-existent directory, throw a DirectoryNotFoundException
vs a System.Runtime.InteropServices.ExternalException.

Fix #31367

* Change exception message to be more intuitive

Use: The directory {0} of the filename {1} does not exist.
instead of: The target directory {0} of the targetPath {1} does not exist.

Fix #31367

* Fix test on unix by using built path.

We were using a hardcoded path with backslashes. That didn't match the built path for the Assert.

* Make Test conditional as it requires GDI+

* Put directory check closer to where it's used to ensure that we
capture it from all Save variations.

* Remove trailing whitespace

* Update test to ensure it doesn't run on the .NET Framework

* Change CheckIfDirectoryExists to ThrowIfDirectoryDoesntExist
to match naming conventions for throw-style methods.

Fix #31367

* Fixes typo in test name

Fix #31367
  • Loading branch information
Macromullet authored Apr 17, 2020
1 parent 80d8920 commit 8981ad7
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -455,4 +455,7 @@
<data name="ValueNotOneOfValues" xml:space="preserve">
<value>The value of the {0} property is not one of the {1} values</value>
</data>
<data name="TargetDirectoryDoesNotExist" xml:space="preserve">
<value>The directory {0} of the filename {1} does not exist.</value>
</data>
</root>
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,11 @@ public void Save(string filename, ImageFormat format)

public void Save(string filename, ImageCodecInfo encoder, EncoderParameters? encoderParams)
{
if (filename == null)
throw new ArgumentNullException(nameof(filename));

ThrowIfDirectoryDoesntExist(filename);

int st;
Guid guid = encoder.Clsid;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@ public void Save(string filename, ImageCodecInfo encoder, EncoderParameters? enc
if (encoder == null)
throw new ArgumentNullException(nameof(encoder));

ThrowIfDirectoryDoesntExist(filename);

IntPtr encoderParamsMemory = IntPtr.Zero;

if (encoderParams != null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,15 @@ public void Dispose()
/// </summary>
public void Save(string filename) => Save(filename, RawFormat);

private static void ThrowIfDirectoryDoesntExist(string filename)
{
var directoryPart = System.IO.Path.GetDirectoryName(filename);
if (!string.IsNullOrEmpty(directoryPart) && !System.IO.Directory.Exists(directoryPart))
{
throw new DirectoryNotFoundException(SR.Format(SR.TargetDirectoryDoesNotExist, directoryPart, filename));
}
}

/// <summary>
/// Gets the width and height of this <see cref='Image'/>.
/// </summary>
Expand Down
11 changes: 11 additions & 0 deletions src/libraries/System.Drawing.Common/tests/ImageTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -199,5 +199,16 @@ public void GetEncoderParameterList_ReturnsExpected(ImageFormat format, Guid[] e
paramList.Param.Select(p => p.Encoder.Guid));
}
}

[SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, ".NET Framework throws ExternalException")]
[ConditionalFact(Helpers.IsDrawingSupported)]
public void Save_InvalidDirectory_ThrowsDirectoryNotFoundException()
{
using (var bitmap = new Bitmap(1, 1))
{
var badTarget = System.IO.Path.Combine("NoSuchDirectory", "NoSuchFile");
AssertExtensions.Throws<DirectoryNotFoundException>(() => bitmap.Save(badTarget), $"The directory NoSuchDirectory of the filename {badTarget} does not exist.");
}
}
}
}

0 comments on commit 8981ad7

Please sign in to comment.