diff --git a/src/System.Drawing.Common/src/Resources/Strings.resx b/src/System.Drawing.Common/src/Resources/Strings.resx index e5b4b7e8d05..0ec4b7edab4 100644 --- a/src/System.Drawing.Common/src/Resources/Strings.resx +++ b/src/System.Drawing.Common/src/Resources/Strings.resx @@ -455,4 +455,7 @@ The value of the {0} property is not one of the {1} values + + The directory {0} of the filename {1} does not exist. + \ No newline at end of file diff --git a/src/System.Drawing.Common/src/System/Drawing/Image.Unix.cs b/src/System.Drawing.Common/src/System/Drawing/Image.Unix.cs index 63bda678e62..ab88eaf4430 100644 --- a/src/System.Drawing.Common/src/System/Drawing/Image.Unix.cs +++ b/src/System.Drawing.Common/src/System/Drawing/Image.Unix.cs @@ -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; diff --git a/src/System.Drawing.Common/src/System/Drawing/Image.Windows.cs b/src/System.Drawing.Common/src/System/Drawing/Image.Windows.cs index ba681220459..4747b9c9ca4 100644 --- a/src/System.Drawing.Common/src/System/Drawing/Image.Windows.cs +++ b/src/System.Drawing.Common/src/System/Drawing/Image.Windows.cs @@ -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) diff --git a/src/System.Drawing.Common/src/System/Drawing/Image.cs b/src/System.Drawing.Common/src/System/Drawing/Image.cs index 8adc6656cc1..2019b33f24f 100644 --- a/src/System.Drawing.Common/src/System/Drawing/Image.cs +++ b/src/System.Drawing.Common/src/System/Drawing/Image.cs @@ -153,6 +153,15 @@ public void Dispose() /// 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)); + } + } + /// /// Gets the width and height of this . /// diff --git a/src/System.Drawing.Common/tests/ImageTests.cs b/src/System.Drawing.Common/tests/ImageTests.cs index e0ac720cd38..120741fa05b 100644 --- a/src/System.Drawing.Common/tests/ImageTests.cs +++ b/src/System.Drawing.Common/tests/ImageTests.cs @@ -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(() => bitmap.Save(badTarget), $"The directory NoSuchDirectory of the filename {badTarget} does not exist."); + } + } } }