{"record":{"id":"a063d01d03057aaa","repo":"SixLabors/ImageSharp","slug":"invalid-clut-dimensions","errorCode":null,"errorMessage":"Invalid CLUT dimensions.","messagePattern":"Invalid CLUT dimensions\\.","errorType":"exception","errorClass":"InvalidIccProfileException","httpStatus":null,"severity":"error","filePath":"src/ImageSharp/Metadata/Profiles/ICC/DataReader/IccDataReader.Lut.cs","lineNumber":154,"sourceCode":"            for (int j = 0; j < outChCount; j++)\n            {\n                values[offset++] = this.ReadSingle();\n            }\n        }\n\n        this.currentIndex = start + (length * outChCount * 4);\n        return new IccClut(values, gridPointCount, IccClutDataType.Float, outChCount);\n    }\n\n    private int GetClutLength(int inputChannelCount, int outputChannelCount, byte[] gridPointCount, int bytesPerValue)\n    {\n        int length = 1;\n        for (int i = 0; i < inputChannelCount; i++)\n        {\n            int gridPoints = gridPointCount[i];\n            if (gridPoints == 0 || length > int.MaxValue / gridPoints)\n            {\n                throw new InvalidIccProfileException(\"Invalid CLUT dimensions.\");\n            }\n\n            length *= gridPoints;\n        }\n\n        long valueCount = (long)length * outputChannelCount;\n        long byteCount = valueCount * bytesPerValue;\n        if (valueCount > int.MaxValue || byteCount > this.data.Length - this.currentIndex)\n        {\n            throw new InvalidIccProfileException(\"The CLUT data is shorter than its declared dimensions.\");\n        }\n\n        return length;\n    }\n}\n","sourceCodeStart":136,"sourceCodeEnd":170,"githubUrl":"https://github.com/SixLabors/ImageSharp/blob/59ce6af6fc29027cda277ef62d4d1694a8acce91/src/ImageSharp/Metadata/Profiles/ICC/DataReader/IccDataReader.Lut.cs#L136-L170","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// caller-side guard before parsing\nstatic bool HasValidClutGrid(byte[] profileBytes)\n{\n    // naive sanity check: file must be at least large enough for a header + tags\n    return profileBytes is { Length: > 128 }; // real validation via ICC tools recommended\n}","handlingStrategy":"validation","validationCode":"// Inspect gridPointCount before parsing (bytes per ICC spec: lut header layout)\n// Reject profiles whose declared grid points are zero or whose implied table size is absurd\nstatic bool PlausibleProfileSize(long fileLength, int channels, int[] gridPoints)\n{\n    long cells = 1;\n    foreach (int g in gridPoints) cells *= g;\n    long bytes = cells * channels; // min 1 byte per value\n    return cells > 0 && bytes <= fileLength;\n}","typeGuard":null,"tryCatchPattern":"try { return new IccProfile(bytes); }\ncatch (InvalidIccProfileException ex)\n{\n    throw new InvalidDataException(\"ICC profile has invalid CLUT grid dimensions\", ex);\n}","preventionTips":["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"],"tags":["icc","clut","overflow","profile-validation"],"backgroundTag":"value-out-of-range","analyzedSha":"59ce6af6fc29027cda277ef62d4d1694a8acce91","analyzedAt":"2026-09-13T18:34:59.331Z","contentChangedAt":"2026-09-13T18:34:59.331Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}