diff --git a/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs b/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs
index 7561afa1ef..057bd74bb4 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)
{
@@ -898,10 +901,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
/// The codelengths
/// 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);
- }
+ private void BuildHuffmanTable(HuffmanTables tables, int index, ReadOnlySpan codeLengths, ReadOnlySpan 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 72db6305dd..549cb3fe09 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 3c98d5be72..a14c4735f5 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 4ae955c323..5977e59cf3 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 1ee3f96757..0ad3edda88 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 fcf311bf15..6abc3bc0ac 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 0000000000..b3a7ce356c
--- /dev/null
+++ b/tests/Images/Input/Jpg/issues/Issue694-Decode-Exif-OutOfRange.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:1b94a283fbe8927ab59745dd67d0b33e90a253e674e5fe4f0ad7594ff868cca2
+size 226421
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 0000000000..4891779878
--- /dev/null
+++ b/tests/Images/Input/Jpg/issues/Issue695-Invalid-EOI.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:e748a684c318b7424dd77b008fe92e179201d0a55106021b453a3fd2a22e9ab6
+size 4805575
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 0000000000..38c5c8d59c
--- /dev/null
+++ b/tests/Images/Input/Jpg/issues/Issue696-Resize-Exif-OutOfRange.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:bb22005e1db0f6da8f49ca57979f8b9aa5db7111b717a53e817e24c04283ab43
+size 3196058