Browse Source

Only exit after multiple EOF hits

pull/2701/head
James Jackson-South 2 years ago
parent
commit
382ee7fb23
  1. 20
      src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegBitReader.cs
  2. 11
      tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs
  3. 1
      tests/ImageSharp.Tests/TestImages.cs
  4. 3
      tests/Images/Input/Jpg/issues/Issue2638.jpg

20
src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegBitReader.cs

@ -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;
@ -31,6 +34,7 @@ internal struct JpegBitReader
this.MarkerPosition = 0;
this.badData = false;
this.NoData = false;
this.eofHitCount = 0;
}
/// <summary>
@ -80,6 +84,9 @@ internal struct JpegBitReader
[MethodImpl(InliningOptions.ShortMethod)]
public bool HasBadMarker() => this.Marker != JpegConstants.Markers.XFF && !this.HasRestartMarker();
[MethodImpl(InliningOptions.ShortMethod)]
public bool HasEndMarker() => this.Marker == JpegConstants.Markers.EOI;
[MethodImpl(InliningOptions.AlwaysInline)]
public void FillBuffer()
{
@ -219,11 +226,16 @@ internal struct JpegBitReader
// 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 passed the end of the file stream 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;

11
tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs

@ -364,4 +364,15 @@ public partial class JpegDecoderTests
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
tests/ImageSharp.Tests/TestImages.cs

@ -316,6 +316,7 @@ public static class TestImages
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
{

3
tests/Images/Input/Jpg/issues/Issue2638.jpg

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:208d5b0b727bbef120a7e090e020a48f99c9e264c2d3939ba749f8620853c1fe
size 70876
Loading…
Cancel
Save