Browse Source

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
pull/3101/head
Andreas 1 month ago
parent
commit
9569449ac4
  1. 12
      src/ImageSharp/Formats/Png/PngDecoderCore.cs
  2. 24
      tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs

12
src/ImageSharp/Formats/Png/PngDecoderCore.cs

@ -214,7 +214,7 @@ internal sealed class PngDecoderCore : ImageDecoderCore
break;
case PngChunkType.FrameData:
{
if (frameCount >= this.maxFrames)
if (frameCount > this.maxFrames)
{
goto EOF;
}
@ -275,7 +275,7 @@ internal sealed class PngDecoderCore : ImageDecoderCore
previousFrameControl = currentFrameControl;
}
if (frameCount >= this.maxFrames)
if (frameCount > this.maxFrames)
{
goto EOF;
}
@ -402,7 +402,7 @@ internal sealed class PngDecoderCore : ImageDecoderCore
break;
case PngChunkType.FrameControl:
++frameCount;
if (frameCount >= this.maxFrames)
if (frameCount > this.maxFrames)
{
break;
}
@ -411,8 +411,12 @@ internal sealed class PngDecoderCore : ImageDecoderCore
break;
case PngChunkType.FrameData:
if (frameCount >= this.maxFrames)
if (frameCount > this.maxFrames)
{
// Must skip the chunk data even when we've hit maxFrames, because TryReadChunk
// restores the stream position to the start of the fdAT data after CRC validation.
this.SkipChunkDataAndCrc(chunk);
this.SkipRemainingFrameDataChunks(buffer);
break;
}

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

@ -423,6 +423,30 @@ public partial class PngDecoderTests
Assert.Equal(48, imageInfo.FrameMetadataCollection.Count);
}
[Fact]
public void Identify_AnimatedPngWithMaxFrames_ReadsFrameCountCorrectly()
{
TestFile testFile = TestFile.Create(TestImages.Png.AnimatedFrameCount);
using MemoryStream stream = new(testFile.Bytes, false);
ImageInfo imageInfo = Image.Identify(new DecoderOptions { MaxFrames = 40 }, stream);
Assert.NotNull(imageInfo);
Assert.Equal(40, imageInfo.FrameMetadataCollection.Count);
}
[Fact]
public void Load_AnimatedPngWithMaxFrames_ReadsFrameCountCorrectly()
{
TestFile testFile = TestFile.Create(TestImages.Png.AnimatedFrameCount);
using MemoryStream stream = new(testFile.Bytes, false);
using Image image = Image.Load(new DecoderOptions { MaxFrames = 40 }, stream);
Assert.NotNull(image);
Assert.Equal(40, image.Frames.Count);
}
[Theory]
[InlineData(1)]
[InlineData(2)]

Loading…
Cancel
Save