Skip to content

Commit

Permalink
Merge pull request #2701 from SixLabors/defect/2638
Browse files Browse the repository at this point in the history
Only exit JPEG scan decoding after multiple EOF hits
  • Loading branch information
JimBobSquarePants authored Mar 19, 2024
2 parents b55ba46 + 8acecda commit 995cfee
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 4 deletions.
17 changes: 13 additions & 4 deletions src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegBitReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ internal struct JpegBitReader
// Whether there is no more good data to pull from the stream for the current mcu.
private bool badData;

// How many times have we hit the eof.
private int eofHitCount;

public JpegBitReader(BufferedReadStream stream)
{
this.stream = stream;
Expand All @@ -31,6 +34,7 @@ public JpegBitReader(BufferedReadStream stream)
this.MarkerPosition = 0;
this.badData = false;
this.NoData = false;
this.eofHitCount = 0;
}

/// <summary>
Expand Down Expand Up @@ -219,11 +223,16 @@ private int ReadStream()
// we know we have hit the EOI and completed decoding the scan buffer.
if (value == -1 || (this.badData && this.data == 0 && this.stream.Position >= this.stream.Length))
{
// We've encountered the end of the file stream which means there's no EOI marker
// We've hit the end of the file stream more times than allowed which means there's no EOI marker
// in the image or the SOS marker has the wrong dimensions set.
this.badData = true;
this.NoData = true;
value = 0;
if (this.eofHitCount > JpegConstants.Huffman.FetchLoop)
{
this.badData = true;
this.NoData = true;
value = 0;
}

this.eofHitCount++;
}

return value;
Expand Down
11 changes: 11 additions & 0 deletions tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -364,4 +364,15 @@ public void Issue2517_DecodeWorks<TPixel>(TestImageProvider<TPixel> provider)
image.DebugSave(provider);
image.CompareToOriginal(provider);
}

// https://github.com/SixLabors/ImageSharp/issues/2638
[Theory]
[WithFile(TestImages.Jpeg.Issues.Issue2638, PixelTypes.Rgba32)]
public void Issue2638_DecodeWorks<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
using Image<TPixel> image = provider.GetImage(JpegDecoder.Instance);
image.DebugSave(provider);
image.CompareToOriginal(provider);
}
}
1 change: 1 addition & 0 deletions tests/ImageSharp.Tests/TestImages.cs
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,7 @@ public static class Issues
public const string HangBadScan = "Jpg/issues/Hang_C438A851.jpg";
public const string Issue2517 = "Jpg/issues/issue2517-bad-d7.jpg";
public const string Issue2067_CommentMarker = "Jpg/issues/issue-2067-comment.jpg";
public const string Issue2638 = "Jpg/issues/Issue2638.jpg";

public static class Fuzz
{
Expand Down
3 changes: 3 additions & 0 deletions tests/Images/Input/Jpg/issues/Issue2638.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 995cfee

Please sign in to comment.