diff --git a/src/ImageSharp.Formats.Jpeg/Components/Decoder/JpegScanDecoder.cs b/src/ImageSharp.Formats.Jpeg/Components/Decoder/JpegScanDecoder.cs index 39ee6687b..329c58951 100644 --- a/src/ImageSharp.Formats.Jpeg/Components/Decoder/JpegScanDecoder.cs +++ b/src/ImageSharp.Formats.Jpeg/Components/Decoder/JpegScanDecoder.cs @@ -118,7 +118,8 @@ namespace ImageSharp.Formats.Jpg /// Reads the blocks from the -s stream, and processes them into the corresponding instances. /// /// The instance - public void ProcessBlocks(JpegDecoderCore decoder) + /// MCUs processed + public int ProcessBlocks(JpegDecoderCore decoder) { int blockCount = 0; int mcu = 0; @@ -229,6 +230,8 @@ namespace ImageSharp.Formats.Jpg // for mx } + + return mcu; } private void ResetDc() diff --git a/src/ImageSharp.Formats.Jpeg/JpegDecoderCore.cs b/src/ImageSharp.Formats.Jpeg/JpegDecoderCore.cs index 3edd6f70e..5ab5764e2 100644 --- a/src/ImageSharp.Formats.Jpeg/JpegDecoderCore.cs +++ b/src/ImageSharp.Formats.Jpeg/JpegDecoderCore.cs @@ -79,6 +79,16 @@ namespace ImageSharp.Formats /// private YCbCrImage ycbcrImage; + /// + /// The MCU target + /// + private int mcuTarget; + + /// + /// The MCUs processed + /// + private int mcusProcessed; + /// /// Initializes a new instance of the class. /// @@ -187,7 +197,7 @@ namespace ImageSharp.Formats } // Process the remaining segments until the End Of Image marker. - while (true) + while (this.mcuTarget < 1 || this.mcuTarget != this.mcusProcessed) { this.ReadFull(this.Temp, 0, 2); while (this.Temp[0] != 0xff) @@ -864,6 +874,7 @@ namespace ImageSharp.Formats /// The vertical MCU count private void MakeImage(int mxx, int myy) { + this.mcuTarget = mxx * myy; if (this.grayImage.IsInitialized || this.ycbcrImage != null) { return; @@ -1395,7 +1406,7 @@ namespace ImageSharp.Formats JpegScanDecoder.Init(&scan, this, remaining); this.Bits = default(Bits); this.MakeImage(scan.XNumberOfMCUs, scan.YNumberOfMCUs); - scan.ProcessBlocks(this); + this.mcusProcessed += scan.ProcessBlocks(this); } /// diff --git a/tests/ImageSharp.Tests/Formats/Jpg/BadEofJpegTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/BadEofJpegTests.cs new file mode 100644 index 000000000..0697dbb64 --- /dev/null +++ b/tests/ImageSharp.Tests/Formats/Jpg/BadEofJpegTests.cs @@ -0,0 +1,38 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using ImageSharp.Formats; +using Xunit; +using Xunit.Abstractions; +// ReSharper disable InconsistentNaming + +namespace ImageSharp.Tests +{ + using System.Numerics; + + using ImageSharp.Formats.Jpg; + using ImageSharp.Processing; + + public class BadEOFJpegTests : MeasureFixture + { + public BadEOFJpegTests(ITestOutputHelper output) + : base(output) + { + } + + [Theory] + [WithFile(TestImages.Jpeg.BadEOF, PixelTypes.Color)] + public void LoadImage(TestImageProvider provider) + where TColor : struct, IPackedPixel, IEquatable + { + var image = provider.GetImage(); + Assert.NotNull(image); + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs index 89b3c0f0d..9e2d21a9b 100644 --- a/tests/ImageSharp.Tests/TestImages.cs +++ b/tests/ImageSharp.Tests/TestImages.cs @@ -51,6 +51,7 @@ namespace ImageSharp.Tests public const string Festzug = "Jpg/Festzug.jpg"; public const string Hiyamugi = "Jpg/Hiyamugi.jpg"; + public const string BadEOF = "Jpg/badeof.jpg"; public const string Snake = "Jpg/Snake.jpg"; public const string Lake = "Jpg/Lake.jpg"; diff --git a/tests/ImageSharp.Tests/TestImages/Formats/Jpg/badeof.jpg b/tests/ImageSharp.Tests/TestImages/Formats/Jpg/badeof.jpg new file mode 100644 index 000000000..1ba3418de Binary files /dev/null and b/tests/ImageSharp.Tests/TestImages/Formats/Jpg/badeof.jpg differ