diff --git a/src/ImageSharp/Formats/Png/PngDecoderCore.cs b/src/ImageSharp/Formats/Png/PngDecoderCore.cs index b0ec73d2a1..0971c3ecfc 100644 --- a/src/ImageSharp/Formats/Png/PngDecoderCore.cs +++ b/src/ImageSharp/Formats/Png/PngDecoderCore.cs @@ -131,6 +131,11 @@ internal sealed class PngDecoderCore : ImageDecoderCore /// private readonly int maxUncompressedLength; + /// + /// A value indicating whether the image data has been read. + /// + private bool hasImageData; + /// /// Initializes a new instance of the class. /// @@ -749,7 +754,11 @@ private void ReadScanlines( where TPixel : unmanaged, IPixel { using ZlibInflateStream inflateStream = new(this.currentStream, getData); - inflateStream.AllocateNewBytes(chunkLength, true); + if (!inflateStream.AllocateNewBytes(chunkLength, !this.hasImageData)) + { + return; + } + DeflateStream dataStream = inflateStream.CompressedStream!; if (this.header.InterlaceMethod is PngInterlaceMode.Adam7) @@ -803,7 +812,7 @@ private void DecodePixelData( int bytesRead = compressedStream.Read(scanSpan, currentRowBytesRead, bytesPerFrameScanline - currentRowBytesRead); if (bytesRead <= 0) { - return; + goto EXIT; } currentRowBytesRead += bytesRead; @@ -848,6 +857,7 @@ private void DecodePixelData( } EXIT: + this.hasImageData = true; blendMemory?.Dispose(); } @@ -906,7 +916,7 @@ private void DecodeInterlacedPixelData( int bytesRead = compressedStream.Read(this.scanline.GetSpan(), currentRowBytesRead, bytesPerInterlaceScanline - currentRowBytesRead); if (bytesRead <= 0) { - return; + goto EXIT; } currentRowBytesRead += bytesRead; @@ -979,6 +989,7 @@ private void DecodeInterlacedPixelData( } EXIT: + this.hasImageData = true; blendMemory?.Dispose(); } diff --git a/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs index 9f3c5f6828..4d058e54e8 100644 --- a/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs @@ -719,10 +719,20 @@ public void Decode_BadPalette(string file) [Theory] [WithFile(TestImages.Png.Issue2752, PixelTypes.Rgba32)] public void CanDecodeJustOneFrame(TestImageProvider provider) - where TPixel : unmanaged, IPixel + where TPixel : unmanaged, IPixel { DecoderOptions options = new() { MaxFrames = 1 }; using Image image = provider.GetImage(PngDecoder.Instance, options); Assert.Equal(1, image.Frames.Count); } + + [Theory] + [WithFile(TestImages.Png.Issue2924, PixelTypes.Rgba32)] + public void CanDecode_Issue2924(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using Image image = provider.GetImage(PngDecoder.Instance); + image.DebugSave(provider); + image.CompareToReferenceOutput(provider); + } } diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs index 373b38eee4..78632e7dce 100644 --- a/tests/ImageSharp.Tests/TestImages.cs +++ b/tests/ImageSharp.Tests/TestImages.cs @@ -160,6 +160,9 @@ public static class Png // Issue 2752: https://github.com/SixLabors/ImageSharp/issues/2752 public const string Issue2752 = "Png/issues/Issue_2752.png"; + // Issue 2924: https://github.com/SixLabors/ImageSharp/issues/2924 + public const string Issue2924 = "Png/issues/Issue_2924.png"; + public static class Bad { public const string MissingDataChunk = "Png/xdtn0g01.png"; diff --git a/tests/Images/External/ReferenceOutput/PngDecoderTests/CanDecode_Issue2924_Rgba32_Issue_2924.png b/tests/Images/External/ReferenceOutput/PngDecoderTests/CanDecode_Issue2924_Rgba32_Issue_2924.png new file mode 100644 index 0000000000..023f346e03 --- /dev/null +++ b/tests/Images/External/ReferenceOutput/PngDecoderTests/CanDecode_Issue2924_Rgba32_Issue_2924.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4347cd89196c09496288724afdd876b227063149bba33615c338ebb474a0cb19 +size 47260 diff --git a/tests/Images/Input/Png/issues/Issue_2924.png b/tests/Images/Input/Png/issues/Issue_2924.png new file mode 100644 index 0000000000..0454642190 --- /dev/null +++ b/tests/Images/Input/Png/issues/Issue_2924.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fd366a2de522041c706729b01a6030df6c82a4e87ea3509cc78a47486f097044 +size 49376