Skip to content

Commit a842e98

Browse files
fredeilJimBobSquarePants
authored andcommitted
Throw UnkownFormatException on Image.Load (#932)
* Throw ImageFormatException on load * Unseal class and make constructor internal - This is so that no one can new it up / inherit it outside of the assembly * Add new exception for distinguish between different exception - This will be used on image.load operations with invalid image streams * ImageFormatException -> UnkownImageFormatException * Add Image.Load throws exception tests
1 parent 6016c11 commit a842e98

File tree

4 files changed

+108
-8
lines changed

4 files changed

+108
-8
lines changed

src/ImageSharp/Common/Exceptions/ImageFormatException.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) Six Labors and contributors.
1+
// Copyright (c) Six Labors and contributors.
22
// Licensed under the Apache License, Version 2.0.
33

44
using System;
@@ -9,14 +9,14 @@ namespace SixLabors.ImageSharp
99
/// The exception that is thrown when the library tries to load
1010
/// an image, which has an invalid format.
1111
/// </summary>
12-
public sealed class ImageFormatException : Exception
12+
public class ImageFormatException : Exception
1313
{
1414
/// <summary>
1515
/// Initializes a new instance of the <see cref="ImageFormatException"/> class with the name of the
1616
/// parameter that causes this exception.
1717
/// </summary>
1818
/// <param name="errorMessage">The error message that explains the reason for this exception.</param>
19-
public ImageFormatException(string errorMessage)
19+
internal ImageFormatException(string errorMessage)
2020
: base(errorMessage)
2121
{
2222
}
@@ -28,7 +28,7 @@ public ImageFormatException(string errorMessage)
2828
/// <param name="errorMessage">The error message that explains the reason for this exception.</param>
2929
/// <param name="innerException">The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic)
3030
/// if no inner exception is specified.</param>
31-
public ImageFormatException(string errorMessage, Exception innerException)
31+
internal ImageFormatException(string errorMessage, Exception innerException)
3232
: base(errorMessage, innerException)
3333
{
3434
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Copyright (c) Six Labors and contributors.
2+
// Licensed under the Apache License, Version 2.0.
3+
4+
using System;
5+
6+
namespace SixLabors.ImageSharp
7+
{
8+
/// <summary>
9+
/// The exception that is thrown when the library tries to load
10+
/// an image which has an unkown format.
11+
/// </summary>
12+
public sealed class UnknownImageFormatException : ImageFormatException
13+
{
14+
/// <summary>
15+
/// Initializes a new instance of the <see cref="UnknownImageFormatException"/> class with the name of the
16+
/// parameter that causes this exception.
17+
/// </summary>
18+
/// <param name="errorMessage">The error message that explains the reason for this exception.</param>
19+
public UnknownImageFormatException(string errorMessage)
20+
: base(errorMessage)
21+
{
22+
}
23+
24+
/// <summary>
25+
/// Initializes a new instance of the <see cref="UnknownImageFormatException"/> class with a specified
26+
/// error message and the exception that is the cause of this exception.
27+
/// </summary>
28+
/// <param name="errorMessage">The error message that explains the reason for this exception.</param>
29+
/// <param name="innerException">The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic)
30+
/// if no inner exception is specified.</param>
31+
public UnknownImageFormatException(string errorMessage, Exception innerException)
32+
: base(errorMessage, innerException)
33+
{
34+
}
35+
}
36+
}

src/ImageSharp/Image.FromStream.cs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) Six Labors and contributors.
1+
// Copyright (c) Six Labors and contributors.
22
// Licensed under the Apache License, Version 2.0.
33

44
using System;
@@ -62,6 +62,7 @@ public static IImageInfo Identify(Configuration config, Stream stream)
6262
/// <param name="stream">The stream containing image information.</param>
6363
/// <param name="format">the mime type of the decoded image.</param>
6464
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
65+
/// <exception cref="UnknownImageFormatException">Image cannot be loaded.</exception>
6566
/// <returns>A new <see cref="Image"/>.</returns>>
6667
public static Image Load(Stream stream, out IImageFormat format) => Load(Configuration.Default, stream, out format);
6768

@@ -71,6 +72,7 @@ public static IImageInfo Identify(Configuration config, Stream stream)
7172
/// </summary>
7273
/// <param name="stream">The stream containing image information.</param>
7374
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
75+
/// <exception cref="UnknownImageFormatException">Image cannot be loaded.</exception>
7476
/// <returns>A new <see cref="Image"/>.</returns>>
7577
public static Image Load(Stream stream) => Load(Configuration.Default, stream);
7678

@@ -81,6 +83,7 @@ public static IImageInfo Identify(Configuration config, Stream stream)
8183
/// <param name="stream">The stream containing image information.</param>
8284
/// <param name="decoder">The decoder.</param>
8385
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
86+
/// <exception cref="UnknownImageFormatException">Image cannot be loaded.</exception>
8487
/// <returns>A new <see cref="Image"/>.</returns>>
8588
public static Image Load(Stream stream, IImageDecoder decoder) => Load(Configuration.Default, stream, decoder);
8689

@@ -92,6 +95,7 @@ public static IImageInfo Identify(Configuration config, Stream stream)
9295
/// <param name="stream">The stream containing image information.</param>
9396
/// <param name="decoder">The decoder.</param>
9497
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
98+
/// <exception cref="UnknownImageFormatException">Image cannot be loaded.</exception>
9599
/// <returns>A new <see cref="Image"/>.</returns>>
96100
public static Image Load(Configuration config, Stream stream, IImageDecoder decoder) =>
97101
WithSeekableStream(config, stream, s => decoder.Decode(config, s));
@@ -102,6 +106,7 @@ public static Image Load(Configuration config, Stream stream, IImageDecoder deco
102106
/// <param name="config">The config for the decoder.</param>
103107
/// <param name="stream">The stream containing image information.</param>
104108
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
109+
/// <exception cref="UnknownImageFormatException">Image cannot be loaded.</exception>
105110
/// <returns>A new <see cref="Image"/>.</returns>>
106111
public static Image Load(Configuration config, Stream stream) => Load(config, stream, out _);
107112

@@ -110,6 +115,7 @@ public static Image Load(Configuration config, Stream stream, IImageDecoder deco
110115
/// </summary>
111116
/// <param name="stream">The stream containing image information.</param>
112117
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
118+
/// <exception cref="UnknownImageFormatException">Image cannot be loaded.</exception>
113119
/// <typeparam name="TPixel">The pixel format.</typeparam>
114120
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>>
115121
public static Image<TPixel> Load<TPixel>(Stream stream)
@@ -122,6 +128,7 @@ public static Image<TPixel> Load<TPixel>(Stream stream)
122128
/// <param name="stream">The stream containing image information.</param>
123129
/// <param name="format">the mime type of the decoded image.</param>
124130
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
131+
/// <exception cref="UnknownImageFormatException">Image cannot be loaded.</exception>
125132
/// <typeparam name="TPixel">The pixel format.</typeparam>
126133
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>>
127134
public static Image<TPixel> Load<TPixel>(Stream stream, out IImageFormat format)
@@ -134,6 +141,7 @@ public static Image<TPixel> Load<TPixel>(Stream stream, out IImageFormat format)
134141
/// <param name="stream">The stream containing image information.</param>
135142
/// <param name="decoder">The decoder.</param>
136143
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
144+
/// <exception cref="UnknownImageFormatException">Image cannot be loaded.</exception>
137145
/// <typeparam name="TPixel">The pixel format.</typeparam>
138146
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>>
139147
public static Image<TPixel> Load<TPixel>(Stream stream, IImageDecoder decoder)
@@ -147,6 +155,7 @@ public static Image<TPixel> Load<TPixel>(Stream stream, IImageDecoder decoder)
147155
/// <param name="stream">The stream containing image information.</param>
148156
/// <param name="decoder">The decoder.</param>
149157
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
158+
/// <exception cref="UnknownImageFormatException">Image cannot be loaded.</exception>
150159
/// <typeparam name="TPixel">The pixel format.</typeparam>
151160
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>>
152161
public static Image<TPixel> Load<TPixel>(Configuration config, Stream stream, IImageDecoder decoder)
@@ -159,6 +168,7 @@ public static Image<TPixel> Load<TPixel>(Configuration config, Stream stream, II
159168
/// <param name="config">The configuration options.</param>
160169
/// <param name="stream">The stream containing image information.</param>
161170
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
171+
/// <exception cref="UnknownImageFormatException">Image cannot be loaded.</exception>
162172
/// <typeparam name="TPixel">The pixel format.</typeparam>
163173
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>>
164174
public static Image<TPixel> Load<TPixel>(Configuration config, Stream stream)
@@ -172,6 +182,7 @@ public static Image<TPixel> Load<TPixel>(Configuration config, Stream stream)
172182
/// <param name="stream">The stream containing image information.</param>
173183
/// <param name="format">the mime type of the decoded image.</param>
174184
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
185+
/// <exception cref="UnknownImageFormatException">Image cannot be loaded.</exception>
175186
/// <typeparam name="TPixel">The pixel format.</typeparam>
176187
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>>
177188
public static Image<TPixel> Load<TPixel>(Configuration config, Stream stream, out IImageFormat format)
@@ -195,7 +206,7 @@ public static Image<TPixel> Load<TPixel>(Configuration config, Stream stream, ou
195206
sb.AppendLine($" - {val.Key.Name} : {val.Value.GetType().Name}");
196207
}
197208

198-
throw new NotSupportedException(sb.ToString());
209+
throw new UnknownImageFormatException(sb.ToString());
199210
}
200211

201212
/// <summary>
@@ -206,6 +217,7 @@ public static Image<TPixel> Load<TPixel>(Configuration config, Stream stream, ou
206217
/// <param name="stream">The stream containing image information.</param>
207218
/// <param name="format">the mime type of the decoded image.</param>
208219
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
220+
/// <exception cref="UnknownImageFormatException">Image cannot be loaded.</exception>
209221
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
210222
public static Image Load(Configuration config, Stream stream, out IImageFormat format)
211223
{
@@ -227,7 +239,7 @@ public static Image Load(Configuration config, Stream stream, out IImageFormat f
227239
sb.AppendLine($" - {val.Key.Name} : {val.Value.GetType().Name}");
228240
}
229241

230-
throw new NotSupportedException(sb.ToString());
242+
throw new UnknownImageFormatException(sb.ToString());
231243
}
232244

233245
private static T WithSeekableStream<T>(Configuration config, Stream stream, Func<Stream, T> action)
@@ -257,4 +269,4 @@ private static T WithSeekableStream<T>(Configuration config, Stream stream, Func
257269
}
258270
}
259271
}
260-
}
272+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright (c) Six Labors and contributors.
2+
// Licensed under the Apache License, Version 2.0.
3+
4+
using System;
5+
using System.IO;
6+
7+
using SixLabors.ImageSharp.Formats;
8+
using SixLabors.ImageSharp.Formats.Bmp;
9+
using SixLabors.ImageSharp.PixelFormats;
10+
using SixLabors.Primitives;
11+
12+
using Xunit;
13+
14+
namespace SixLabors.ImageSharp.Tests
15+
{
16+
public partial class ImageTests
17+
{
18+
public class Load_FromStream_Throws : IDisposable
19+
{
20+
private static readonly byte[] Data = new byte[] { 0x01 };
21+
22+
private MemoryStream Stream { get; } = new MemoryStream(Data);
23+
24+
[Fact]
25+
public void Image_Load_Throws_UknownImageFormatException()
26+
{
27+
Assert.Throws<UnknownImageFormatException>(() =>
28+
{
29+
using (var img = Image.Load(Configuration.Default, this.Stream, out IImageFormat format))
30+
{
31+
}
32+
});
33+
}
34+
35+
[Fact]
36+
public void Image_Load_T_Throws_UknownImageFormatException()
37+
{
38+
Assert.Throws<UnknownImageFormatException>(() =>
39+
{
40+
using (var img = Image.Load<Rgba32>(Configuration.Default, this.Stream, out IImageFormat format))
41+
{
42+
}
43+
});
44+
}
45+
46+
public void Dispose()
47+
{
48+
this.Stream?.Dispose();
49+
}
50+
}
51+
}
52+
}

0 commit comments

Comments
 (0)