-
-
Notifications
You must be signed in to change notification settings - Fork 891
Description
Prerequisites
- I have written a descriptive issue title
- I have verified that I am running the latest version of ImageSharp
- I have verified if the problem exist in both
DEBUGandRELEASEmode - I have searched open and closed issues to ensure it has not already been reported
ImageSharp version
3.1.12
Other ImageSharp packages and versions
N/A — only SixLabors.ImageSharp
Environment (Operating system, version and so on)
Linux (WSL2, Ubuntu 22.04) and Windows 10
.NET Framework version
.NET 10.0 (SDK 10.0.103 / Runtime 10.0.3)
Description
A crafted 24-byte PNG file with a truncated pHYs chunk causes an unhandled IndexOutOfRangeException in PngPhysical.Parse. The pHYs chunk normally contains 9 bytes (4 + 4 + 1), but the parser does not validate the data length before reading.
This exception is not part of the ImageSharp exception hierarchy (ImageFormatException / InvalidImageContentException), so applications following the documented error handling pattern cannot catch it.
The root cause is that PngPhysical.Parse() accesses fixed offsets in the data span without first checking that the span has the required 9 bytes.
Found by coverage-guided fuzzing with SharpFuzz + AFL++.
Steps to Reproduce
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
// 24 bytes — PNG signature + truncated pHYs chunk
byte[] payload = Convert.FromHexString(
"89504e470d0a1a0a3030303070485973" +
"3030303030303030");
using var stream = new MemoryStream(payload);
using var image = Image.Load<Rgba32>(stream); // throws IndexOutOfRangeExceptionStack trace
System.IndexOutOfRangeException: Index was outside the bounds of the array.
at SixLabors.ImageSharp.Formats.Png.Chunks.PngPhysical.Parse(ReadOnlySpan`1 data)
at SixLabors.ImageSharp.Formats.Png.PngDecoderCore.ReadPhysicalChunk(ImageMetadata metadata, ReadOnlySpan`1 data)
at SixLabors.ImageSharp.Formats.Png.PngDecoderCore.Decode[TPixel](BufferedReadStream stream, CancellationToken cancellationToken)
at SixLabors.ImageSharp.Formats.ImageDecoderCore.Decode[TPixel](Configuration configuration, Stream stream, CancellationToken cancellationToken)
at SixLabors.ImageSharp.Image.Load[TPixel](Stream stream)
Root Cause & Suggested Fix
PngPhysical.Parse() should validate the span length before reading:
public static PngPhysical Parse(ReadOnlySpan<byte> data)
{
if (data.Length < 9)
{
ThrowInvalidImageContentException("pHYs chunk is too short");
}
// ... existing code
}Images
N/A — the reproduction is fully inline above (24-byte constructed PNG).