diff --git a/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs b/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs
index cd960a241..b46b4b604 100644
--- a/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs
+++ b/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs
@@ -268,7 +268,10 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
this.fastACTables = new FastACTables(this.configuration.MemoryAllocator);
}
- while (fileMarker.Marker != JpegConstants.Markers.EOI)
+ // Break only when we discover a valid EOI marker.
+ // https://github.com/SixLabors/ImageSharp/issues/695
+ while (fileMarker.Marker != JpegConstants.Markers.EOI
+ || (fileMarker.Marker == JpegConstants.Markers.EOI && fileMarker.Invalid))
{
if (!fileMarker.Invalid)
{
@@ -914,9 +917,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
/// The values
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void BuildHuffmanTable(HuffmanTables tables, int index, ReadOnlySpan codeLengths, ReadOnlySpan values)
- {
- tables[index] = new HuffmanTable(this.configuration.MemoryAllocator, codeLengths, values);
- }
+ => tables[index] = new HuffmanTable(this.configuration.MemoryAllocator, codeLengths, values);
///
/// Reads a from the stream advancing it by two bytes
diff --git a/src/ImageSharp/MetaData/Profiles/Exif/ExifReader.cs b/src/ImageSharp/MetaData/Profiles/Exif/ExifReader.cs
index 72db6305d..549cb3fe0 100644
--- a/src/ImageSharp/MetaData/Profiles/Exif/ExifReader.cs
+++ b/src/ImageSharp/MetaData/Profiles/Exif/ExifReader.cs
@@ -88,19 +88,19 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Exif
}
uint ifdOffset = this.ReadUInt32();
- this.AddValues(values, (int)ifdOffset);
+ this.AddValues(values, ifdOffset);
uint thumbnailOffset = this.ReadUInt32();
- this.GetThumbnail((int)thumbnailOffset);
+ this.GetThumbnail(thumbnailOffset);
if (this.exifOffset != 0)
{
- this.AddValues(values, (int)this.exifOffset);
+ this.AddValues(values, this.exifOffset);
}
if (this.gpsOffset != 0)
{
- this.AddValues(values, (int)this.gpsOffset);
+ this.AddValues(values, this.gpsOffset);
}
return values;
@@ -153,9 +153,14 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Exif
///
/// The values.
/// The index.
- private void AddValues(List values, int index)
+ private void AddValues(List values, uint index)
{
- this.position = index;
+ if (index > (uint)this.exifData.Length)
+ {
+ return;
+ }
+
+ this.position = (int)index;
int count = this.ReadUInt16();
for (int i = 0; i < count; i++)
@@ -431,7 +436,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Exif
return null;
}
- private void GetThumbnail(int offset)
+ private void GetThumbnail(uint offset)
{
var values = new List();
this.AddValues(values, offset);
@@ -515,10 +520,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Exif
return new Rational(numerator, denominator, false);
}
- private sbyte ConvertToSignedByte(ReadOnlySpan buffer)
- {
- return unchecked((sbyte)buffer[0]);
- }
+ private sbyte ConvertToSignedByte(ReadOnlySpan buffer) => unchecked((sbyte)buffer[0]);
private int ConvertToInt32(ReadOnlySpan buffer) // SignedLong in Exif Specification
{
diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Images.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Images.cs
index 3c98d5be7..a14c4735f 100644
--- a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Images.cs
+++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Images.cs
@@ -21,7 +21,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
TestImages.Jpeg.Baseline.Bad.BadEOF,
TestImages.Jpeg.Issues.MultiHuffmanBaseline394,
TestImages.Jpeg.Baseline.MultiScanBaselineCMYK,
- TestImages.Jpeg.Baseline.Bad.BadRST
+ TestImages.Jpeg.Baseline.Bad.BadRST,
+ TestImages.Jpeg.Issues.MultiHuffmanBaseline394,
+ TestImages.Jpeg.Issues.ExifDecodeOutOfRange694,
+ TestImages.Jpeg.Issues.InvalidEOI695,
+ TestImages.Jpeg.Issues.ExifResizeOutOfRange696
};
public static string[] ProgressiveTestJpegs =
diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs
index 4ae955c32..5977e59cf 100644
--- a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs
+++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs
@@ -48,6 +48,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
TestImages.Jpeg.Issues.BadZigZagProgressive385,
TestImages.Jpeg.Issues.NoEoiProgressive517,
TestImages.Jpeg.Issues.BadRstProgressive518,
+ TestImages.Jpeg.Issues.InvalidEOI695,
+ TestImages.Jpeg.Issues.ExifResizeOutOfRange696
};
return !TestEnvironment.Is64BitProcess && largeImagesToSkipOn32Bit.Contains(provider.SourceFileOrDescription);
diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs
index 1ee3f9675..0ad3edda8 100644
--- a/tests/ImageSharp.Tests/TestImages.cs
+++ b/tests/ImageSharp.Tests/TestImages.cs
@@ -152,6 +152,9 @@ namespace SixLabors.ImageSharp.Tests
public const string BadRstProgressive518 = "Jpg/issues/Issue518-Bad-RST-Progressive.jpg";
public const string InvalidCast520 = "Jpg/issues/Issue520-InvalidCast.jpg";
public const string DhtHasWrongLength624 = "Jpg/issues/Issue624-DhtHasWrongLength-Progressive-N.jpg";
+ public const string ExifDecodeOutOfRange694 = "Jpg/issues/Issue694-Decode-Exif-OutOfRange.jpg";
+ public const string InvalidEOI695 = "Jpg/issues/Issue695-Invalid-EOI.jpg";
+ public const string ExifResizeOutOfRange696 = "Jpg/issues/Issue696-Resize-Exif-OutOfRange.jpg";
}
public static readonly string[] All = Baseline.All.Concat(Progressive.All).ToArray();
diff --git a/tests/Images/External b/tests/Images/External
index fcf311bf1..6abc3bc0a 160000
--- a/tests/Images/External
+++ b/tests/Images/External
@@ -1 +1 @@
-Subproject commit fcf311bf15bea061e552e4cc357cafe2d4f4bd70
+Subproject commit 6abc3bc0ac253a24c9e88e68d7b7d853350a85da
diff --git a/tests/Images/Input/Jpg/issues/Issue694-Decode-Exif-OutOfRange.jpg b/tests/Images/Input/Jpg/issues/Issue694-Decode-Exif-OutOfRange.jpg
new file mode 100644
index 000000000..cfb8424c7
Binary files /dev/null and b/tests/Images/Input/Jpg/issues/Issue694-Decode-Exif-OutOfRange.jpg differ
diff --git a/tests/Images/Input/Jpg/issues/Issue695-Invalid-EOI.jpg b/tests/Images/Input/Jpg/issues/Issue695-Invalid-EOI.jpg
new file mode 100644
index 000000000..e106c1a19
Binary files /dev/null and b/tests/Images/Input/Jpg/issues/Issue695-Invalid-EOI.jpg differ
diff --git a/tests/Images/Input/Jpg/issues/Issue696-Resize-Exif-OutOfRange.jpg b/tests/Images/Input/Jpg/issues/Issue696-Resize-Exif-OutOfRange.jpg
new file mode 100644
index 000000000..ca18ce5b2
Binary files /dev/null and b/tests/Images/Input/Jpg/issues/Issue696-Resize-Exif-OutOfRange.jpg differ