{"record":{"id":"4b8b35db220721ab","repo":"SixLabors/ImageSharp","slug":"the-clut-data-is-shorter-than-its-declared-dimensions","errorCode":null,"errorMessage":"The CLUT data is shorter than its declared dimensions.","messagePattern":"The CLUT data is shorter than its declared dimensions\\.","errorType":"exception","errorClass":"InvalidIccProfileException","httpStatus":null,"severity":"error","filePath":"src/ImageSharp/Metadata/Profiles/ICC/DataReader/IccDataReader.Lut.cs","lineNumber":164,"sourceCode":"    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":146,"sourceCodeEnd":170,"githubUrl":"https://github.com/SixLabors/ImageSharp/blob/59ce6af6fc29027cda277ef62d4d1694a8acce91/src/ImageSharp/Metadata/Profiles/ICC/DataReader/IccDataReader.Lut.cs#L146-L170","documentation":"After computing the expected CLUT size (gridLength * outputChannels * bytesPerValue), the reader checks that enough bytes actually remain in the tag data. If the declared dimensions imply more data than the buffer holds, the profile is declared invalid rather than being partially parsed.","triggerScenarios":"Reading a lutAtoB/lutBToA/lut16 tag whose CLUT header declares grid dimensions and channel counts whose implied byte count exceeds the remaining tag data length; truncated profile files.","commonSituations":"Truncated ICC profiles (incomplete downloads, sliced files); profiles whose tag offsets/lengths disagree with actual tag data; corrupt binaries.","solutions":["Re-obtain a complete, uncorrupted copy of the ICC profile.","Validate tag table offsets and lengths against the file size before parsing.","Catch InvalidIccProfileException and fall back to a non-CLUT rendering intent or a default profile."],"exampleFix":"// before: parse regardless of integrity\nvar profile = new IccProfile(truncatedBytes);\n\n// after: degrade gracefully on corrupt CLUT data\ntry\n{\n    var profile = new IccProfile(truncatedBytes);\n}\ncatch (InvalidIccProfileException ex) when (ex.Message.Contains(\"CLUT\"))\n{\n    profile = IccProfile.Default; // or disable color management\n}","handlingStrategy":"try-catch","validationCode":"// Basic integrity check before parsing\nif (bytes.Length < headerSize + declaredTagTableSize)\n    throw new InvalidDataException(\"ICC profile is truncated\");","typeGuard":null,"tryCatchPattern":"try\n{\n    var profile = new IccProfile(bytes);\n}\ncatch (InvalidIccProfileException ex) when (ex.Message.Contains(\"shorter than\"))\n{\n    // profile data truncated; use fallback transform\n    return ColorManagementFallback;\n}","preventionTips":["Verify complete file transfer before parsing (compare content length)","Check that tag offsets + tag sizes fit inside the file","Re-download profiles that arrive corrupted","Treat profiles as untrusted input and always catch InvalidIccProfileException"],"tags":["icc","clut","truncated-data","profile-validation"],"backgroundTag":"file-read-failed","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"}