Skip to content

Commit c2a8d6f

Browse files
Merge pull request #2926 from SixLabors/js/v4-issue-2924
Do not attempt to decode iDAT chunks when image is fully decoded.
2 parents d8b464b + edc9b52 commit c2a8d6f

File tree

5 files changed

+34
-4
lines changed

5 files changed

+34
-4
lines changed

src/ImageSharp/Formats/Png/PngDecoderCore.cs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,11 @@ internal sealed class PngDecoderCore : ImageDecoderCore
131131
/// </summary>
132132
private readonly int maxUncompressedLength;
133133

134+
/// <summary>
135+
/// A value indicating whether the image data has been read.
136+
/// </summary>
137+
private bool hasImageData;
138+
134139
/// <summary>
135140
/// Initializes a new instance of the <see cref="PngDecoderCore"/> class.
136141
/// </summary>
@@ -749,7 +754,11 @@ private void ReadScanlines<TPixel>(
749754
where TPixel : unmanaged, IPixel<TPixel>
750755
{
751756
using ZlibInflateStream inflateStream = new(this.currentStream, getData);
752-
inflateStream.AllocateNewBytes(chunkLength, true);
757+
if (!inflateStream.AllocateNewBytes(chunkLength, !this.hasImageData))
758+
{
759+
return;
760+
}
761+
753762
DeflateStream dataStream = inflateStream.CompressedStream!;
754763

755764
if (this.header.InterlaceMethod is PngInterlaceMode.Adam7)
@@ -803,7 +812,7 @@ private void DecodePixelData<TPixel>(
803812
int bytesRead = compressedStream.Read(scanSpan, currentRowBytesRead, bytesPerFrameScanline - currentRowBytesRead);
804813
if (bytesRead <= 0)
805814
{
806-
return;
815+
goto EXIT;
807816
}
808817

809818
currentRowBytesRead += bytesRead;
@@ -848,6 +857,7 @@ private void DecodePixelData<TPixel>(
848857
}
849858

850859
EXIT:
860+
this.hasImageData = true;
851861
blendMemory?.Dispose();
852862
}
853863

@@ -906,7 +916,7 @@ private void DecodeInterlacedPixelData<TPixel>(
906916
int bytesRead = compressedStream.Read(this.scanline.GetSpan(), currentRowBytesRead, bytesPerInterlaceScanline - currentRowBytesRead);
907917
if (bytesRead <= 0)
908918
{
909-
return;
919+
goto EXIT;
910920
}
911921

912922
currentRowBytesRead += bytesRead;
@@ -979,6 +989,7 @@ private void DecodeInterlacedPixelData<TPixel>(
979989
}
980990

981991
EXIT:
992+
this.hasImageData = true;
982993
blendMemory?.Dispose();
983994
}
984995

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -719,10 +719,20 @@ public void Decode_BadPalette(string file)
719719
[Theory]
720720
[WithFile(TestImages.Png.Issue2752, PixelTypes.Rgba32)]
721721
public void CanDecodeJustOneFrame<TPixel>(TestImageProvider<TPixel> provider)
722-
where TPixel : unmanaged, IPixel<TPixel>
722+
where TPixel : unmanaged, IPixel<TPixel>
723723
{
724724
DecoderOptions options = new() { MaxFrames = 1 };
725725
using Image<TPixel> image = provider.GetImage(PngDecoder.Instance, options);
726726
Assert.Equal(1, image.Frames.Count);
727727
}
728+
729+
[Theory]
730+
[WithFile(TestImages.Png.Issue2924, PixelTypes.Rgba32)]
731+
public void CanDecode_Issue2924<TPixel>(TestImageProvider<TPixel> provider)
732+
where TPixel : unmanaged, IPixel<TPixel>
733+
{
734+
using Image<TPixel> image = provider.GetImage(PngDecoder.Instance);
735+
image.DebugSave(provider);
736+
image.CompareToReferenceOutput(provider);
737+
}
728738
}

tests/ImageSharp.Tests/TestImages.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,9 @@ public static class Png
160160
// Issue 2752: https://github.com/SixLabors/ImageSharp/issues/2752
161161
public const string Issue2752 = "Png/issues/Issue_2752.png";
162162

163+
// Issue 2924: https://github.com/SixLabors/ImageSharp/issues/2924
164+
public const string Issue2924 = "Png/issues/Issue_2924.png";
165+
163166
public static class Bad
164167
{
165168
public const string MissingDataChunk = "Png/xdtn0g01.png";
Lines changed: 3 additions & 0 deletions
Loading
Lines changed: 3 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)