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