Skip to content

Commit a29c6fd

Browse files
Merge pull request #2702 from SixLabors/backport/2638
Backport - Only exit JPEG scan decoding after multiple EOF hits
2 parents 3f22857 + ea12c0d commit a29c6fd

File tree

4 files changed

+28
-4
lines changed

4 files changed

+28
-4
lines changed

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

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ internal struct JpegBitReader
2222
// Whether there is no more good data to pull from the stream for the current mcu.
2323
private bool badData;
2424

25+
// How many times have we hit the eof.
26+
private int eofHitCount;
27+
2528
public JpegBitReader(BufferedReadStream stream)
2629
{
2730
this.stream = stream;
@@ -31,6 +34,7 @@ public JpegBitReader(BufferedReadStream stream)
3134
this.MarkerPosition = 0;
3235
this.badData = false;
3336
this.NoData = false;
37+
this.eofHitCount = 0;
3438
}
3539

3640
/// <summary>
@@ -219,11 +223,16 @@ private int ReadStream()
219223
// we know we have hit the EOI and completed decoding the scan buffer.
220224
if (value == -1 || (this.badData && this.data == 0 && this.stream.Position >= this.stream.Length))
221225
{
222-
// We've encountered the end of the file stream which means there's no EOI marker
226+
// We've hit the end of the file stream more times than allowed which means there's no EOI marker
223227
// in the image or the SOS marker has the wrong dimensions set.
224-
this.badData = true;
225-
this.NoData = true;
226-
value = 0;
228+
if (this.eofHitCount > JpegConstants.Huffman.FetchLoop)
229+
{
230+
this.badData = true;
231+
this.NoData = true;
232+
value = 0;
233+
}
234+
235+
this.eofHitCount++;
227236
}
228237

229238
return value;

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,4 +364,15 @@ public void Issue2517_DecodeWorks<TPixel>(TestImageProvider<TPixel> provider)
364364
image.DebugSave(provider);
365365
image.CompareToOriginal(provider);
366366
}
367+
368+
// https://github.com/SixLabors/ImageSharp/issues/2638
369+
[Theory]
370+
[WithFile(TestImages.Jpeg.Issues.Issue2638, PixelTypes.Rgba32)]
371+
public void Issue2638_DecodeWorks<TPixel>(TestImageProvider<TPixel> provider)
372+
where TPixel : unmanaged, IPixel<TPixel>
373+
{
374+
using Image<TPixel> image = provider.GetImage(JpegDecoder.Instance);
375+
image.DebugSave(provider);
376+
image.CompareToOriginal(provider);
377+
}
367378
}

tests/ImageSharp.Tests/TestImages.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,7 @@ public static class Issues
315315
public const string Issue2564 = "Jpg/issues/issue-2564.jpg";
316316
public const string HangBadScan = "Jpg/issues/Hang_C438A851.jpg";
317317
public const string Issue2517 = "Jpg/issues/issue2517-bad-d7.jpg";
318+
public const string Issue2638 = "Jpg/issues/Issue2638.jpg";
318319

319320
public static class Fuzz
320321
{
Lines changed: 3 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)