diff --git a/src/ImageSharp/Formats/Png/PngDecoderCore.cs b/src/ImageSharp/Formats/Png/PngDecoderCore.cs index cef8396d4b..f6dad651b7 100644 --- a/src/ImageSharp/Formats/Png/PngDecoderCore.cs +++ b/src/ImageSharp/Formats/Png/PngDecoderCore.cs @@ -125,6 +125,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. /// @@ -746,7 +751,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) @@ -800,7 +809,7 @@ private void DecodePixelData( int bytesRead = compressedStream.Read(scanSpan, currentRowBytesRead, bytesPerFrameScanline - currentRowBytesRead); if (bytesRead <= 0) { - return; + goto EXIT; } currentRowBytesRead += bytesRead; @@ -845,6 +854,7 @@ private void DecodePixelData( } EXIT: + this.hasImageData = true; blendMemory?.Dispose(); } @@ -903,7 +913,7 @@ private void DecodeInterlacedPixelData( int bytesRead = compressedStream.Read(this.scanline.GetSpan(), currentRowBytesRead, bytesPerInterlaceScanline - currentRowBytesRead); if (bytesRead <= 0) { - return; + goto EXIT; } currentRowBytesRead += bytesRead; @@ -976,6 +986,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 11af57e39f..5a5dd9aaa7 100644 --- a/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs @@ -705,10 +705,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 6463f799b5..0c73860e9c 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