SixLabors/ImageSharp · error · InvalidIccProfileException

Invalid CLUT dimensions.

Error message

Invalid CLUT dimensions.

What it means

GetClutLength validates the CLUT grid dimensions before allocating or reading data. It throws when a grid point count is zero, or when multiplying the per-axis grid point counts would overflow int.MaxValue. This prevents absurd or corrupt dimension values from causing overflow or huge allocations.

Solutions

  1. Fix the source profile so every CLUT grid point count is >= 1 and the total table size is realistic.
  2. Reject the profile before use by validating grid point counts yourself, or catch InvalidIccProfileException.
  3. Verify the profile's input channel count matches the grid point count array length.

Example fix

// caller-side guard before parsing
static bool HasValidClutGrid(byte[] profileBytes)
{
    // naive sanity check: file must be at least large enough for a header + tags
    return profileBytes is { Length: > 128 }; // real validation via ICC tools recommended
}
Defensive patterns

Strategy: validation

Validate before calling

// Inspect gridPointCount before parsing (bytes per ICC spec: lut header layout)
// Reject profiles whose declared grid points are zero or whose implied table size is absurd
static bool PlausibleProfileSize(long fileLength, int channels, int[] gridPoints)
{
    long cells = 1;
    foreach (int g in gridPoints) cells *= g;
    long bytes = cells * channels; // min 1 byte per value
    return cells > 0 && bytes <= fileLength;
}

Try / catch

try { return new IccProfile(bytes); }
catch (InvalidIccProfileException ex)
{
    throw new InvalidDataException("ICC profile has invalid CLUT grid dimensions", ex);
}

Prevention

When it happens

Trigger: Reading a lutAToB/lutBToA/lut16 tag where the CLUT gridPointCount array contains a 0 for any input channel, or the product of grid point counts overflows a 32-bit int (e.g. many channels with large grid counts).

Common situations: Corrupt or hand-crafted ICC profile binaries; profiles where the input-channel count byte disagrees with the grid-point-count table; fuzzed files targeting image libraries.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of SixLabors/ImageSharp@59ce6af6fc (2026-09-13). Data as JSON: /api/errors/a063d01d03057aaa. Report an issue: GitHub.

Appendix: source

Thrown at src/ImageSharp/Metadata/Profiles/ICC/DataReader/IccDataReader.Lut.cs:154

            for (int j = 0; j < outChCount; j++)
            {
                values[offset++] = this.ReadSingle();
            }
        }

        this.currentIndex = start + (length * outChCount * 4);
        return new IccClut(values, gridPointCount, IccClutDataType.Float, outChCount);
    }

    private int GetClutLength(int inputChannelCount, int outputChannelCount, byte[] gridPointCount, int bytesPerValue)
    {
        int length = 1;
        for (int i = 0; i < inputChannelCount; i++)
        {
            int gridPoints = gridPointCount[i];
            if (gridPoints == 0 || length > int.MaxValue / gridPoints)
            {
                throw new InvalidIccProfileException("Invalid CLUT dimensions.");
            }

            length *= gridPoints;
        }

        long valueCount = (long)length * outputChannelCount;
        long byteCount = valueCount * bytesPerValue;
        if (valueCount > int.MaxValue || byteCount > this.data.Length - this.currentIndex)
        {
            throw new InvalidIccProfileException("The CLUT data is shorter than its declared dimensions.");
        }

        return length;
    }
}

View on GitHub (pinned to 59ce6af6fc)