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
- Fix the source profile so every CLUT grid point count is >= 1 and the total table size is realistic.
- Reject the profile before use by validating grid point counts yourself, or catch InvalidIccProfileException.
- 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
- Sanity-check input channel counts and grid point arrays in profile generators
- Reject profiles with zero grid point counts early
- Avoid hand-editing profile binaries
- Fuzz-test your profile ingestion path if you accept untrusted profiles
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
- Invalid CLUT size of
- The CLUT data is shorter than its declared dimensions.
- ICC conversion supports at most four input and output…
- Invalid calculation type
- ICC conversion supports at most four input and output…
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)