Skip to content

Commit 9569449

Browse files
Fix MaxFrames handling in PNG decoder
- Change >= to > for correct MaxFrames boundary - Skip fdAT chunk data when hitting maxFrames in Identify to maintain stream alignment - Add tests for Identify and Load with MaxFrames
1 parent a76c02f commit 9569449

File tree

2 files changed

+32
-4
lines changed

2 files changed

+32
-4
lines changed

src/ImageSharp/Formats/Png/PngDecoderCore.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ protected override Image<TPixel> Decode<TPixel>(BufferedReadStream stream, Cance
214214
break;
215215
case PngChunkType.FrameData:
216216
{
217-
if (frameCount >= this.maxFrames)
217+
if (frameCount > this.maxFrames)
218218
{
219219
goto EOF;
220220
}
@@ -275,7 +275,7 @@ protected override Image<TPixel> Decode<TPixel>(BufferedReadStream stream, Cance
275275
previousFrameControl = currentFrameControl;
276276
}
277277

278-
if (frameCount >= this.maxFrames)
278+
if (frameCount > this.maxFrames)
279279
{
280280
goto EOF;
281281
}
@@ -402,7 +402,7 @@ protected override ImageInfo Identify(BufferedReadStream stream, CancellationTok
402402
break;
403403
case PngChunkType.FrameControl:
404404
++frameCount;
405-
if (frameCount >= this.maxFrames)
405+
if (frameCount > this.maxFrames)
406406
{
407407
break;
408408
}
@@ -411,8 +411,12 @@ protected override ImageInfo Identify(BufferedReadStream stream, CancellationTok
411411

412412
break;
413413
case PngChunkType.FrameData:
414-
if (frameCount >= this.maxFrames)
414+
if (frameCount > this.maxFrames)
415415
{
416+
// Must skip the chunk data even when we've hit maxFrames, because TryReadChunk
417+
// restores the stream position to the start of the fdAT data after CRC validation.
418+
this.SkipChunkDataAndCrc(chunk);
419+
this.SkipRemainingFrameDataChunks(buffer);
416420
break;
417421
}
418422

tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,30 @@ public void Identify_AnimatedPng_ReadsFrameCountCorrectly()
423423
Assert.Equal(48, imageInfo.FrameMetadataCollection.Count);
424424
}
425425

426+
[Fact]
427+
public void Identify_AnimatedPngWithMaxFrames_ReadsFrameCountCorrectly()
428+
{
429+
TestFile testFile = TestFile.Create(TestImages.Png.AnimatedFrameCount);
430+
431+
using MemoryStream stream = new(testFile.Bytes, false);
432+
ImageInfo imageInfo = Image.Identify(new DecoderOptions { MaxFrames = 40 }, stream);
433+
434+
Assert.NotNull(imageInfo);
435+
Assert.Equal(40, imageInfo.FrameMetadataCollection.Count);
436+
}
437+
438+
[Fact]
439+
public void Load_AnimatedPngWithMaxFrames_ReadsFrameCountCorrectly()
440+
{
441+
TestFile testFile = TestFile.Create(TestImages.Png.AnimatedFrameCount);
442+
443+
using MemoryStream stream = new(testFile.Bytes, false);
444+
using Image image = Image.Load(new DecoderOptions { MaxFrames = 40 }, stream);
445+
446+
Assert.NotNull(image);
447+
Assert.Equal(40, image.Frames.Count);
448+
}
449+
426450
[Theory]
427451
[InlineData(1)]
428452
[InlineData(2)]

0 commit comments

Comments
 (0)