Skip to content

IndexOutOfRangeException in AssignColorPalette when tRNS chunk exceeds PLTE entries #3082

@pawlos

Description

@pawlos

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 DEBUG and RELEASE mode
  • 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 PNG file with a tRNS chunk containing more alpha entries than there are PLTE palette entries causes an unhandled IndexOutOfRangeException in PngDecoderCore.AssignColorPalette. The PLTE has 2 entries (6 bytes) but the tRNS provides 18 alpha bytes, and the palette assignment loop indexes past the palette array.

This exception is not part of the ImageSharp exception hierarchy, so applications following the documented error handling pattern cannot catch it.

Found by coverage-guided fuzzing with SharpFuzz + AFL++.

Steps to Reproduce

using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;

// 103 bytes — valid palette PNG with tRNS longer than PLTE
byte[] payload = Convert.FromHexString(
    "89504e470d0a1a0a0000000d4948445200000001000000010803000000" +
    "28cb34bb00000006504c5445ff000000ff00d287ef71000000127452" +
    "4e53303030303030303030303030303030303030303030300000000a" +
    "49444154789c636000000002000148afa471");

using var stream = new MemoryStream(payload);
using var image = Image.Load<Rgba32>(stream);  // throws IndexOutOfRangeException

Stack trace

System.IndexOutOfRangeException: Index was outside the bounds of the array.
   at SixLabors.ImageSharp.Formats.Png.PngDecoderCore.AssignColorPalette(
       ReadOnlySpan`1 palette, ReadOnlySpan`1 alpha, PngMetadata pngMetadata)
   at SixLabors.ImageSharp.Formats.Png.PngDecoderCore.Decode[TPixel](
       BufferedReadStream stream, CancellationToken cancellationToken)
   at SixLabors.ImageSharp.Formats.ImageDecoderCore.Decode[TPixel](...)
   at SixLabors.ImageSharp.Image.Load[TPixel](Stream stream)

Root Cause & Suggested Fix

In AssignColorPalette (line 1260), the loop iterates over alpha.Length but indexes into colorTable which has palette.Length / 3 entries. When a malformed tRNS chunk contains more alpha values than there are palette entries, the index exceeds the array bounds.

The PNG spec (section 11.3.1.1) is explicit: "the tRNS chunk must not contain more alpha values than there are palette entries". Since this is a spec violation, the decoder should reject the input with InvalidImageContentException, consistent with how ImageSharp handles other PNG spec violations:

if (alpha.Length > colorTable.Length)
{
    throw new InvalidImageContentException(
        "The tRNS chunk contains more alpha values than there are palette entries.");
}

Images

N/A — the reproduction is fully inline above.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions