{"record":{"id":"733a5ee5ff7254c5","repo":"SixLabors/ImageSharp","slug":"the-ani-riff-container-size-is-invalid","errorCode":null,"errorMessage":"The ANI RIFF container size is invalid.","messagePattern":"The ANI RIFF container size is invalid\\.","errorType":"exception","errorClass":"InvalidImageContentException","httpStatus":null,"severity":"error","filePath":"src/ImageSharp/Formats/Ani/AniDecoderCore.cs","lineNumber":256,"sourceCode":"        this.sequence?.Dispose();\n        this.rates?.Dispose();\n        this.sequence = null;\n        this.rates = null;\n\n        long containerStart = stream.Position;\n        Span<byte> riffHeader = this.buffer[..AniConstants.RiffHeaderSize];\n        ReadExactly(stream, riffHeader, \"RIFF header\");\n\n        if (!riffHeader[..4].SequenceEqual(AniConstants.RiffFourCc)\n            || !riffHeader.Slice(8, 4).SequenceEqual(AniConstants.AniFormTypeFourCc))\n        {\n            throw new InvalidImageContentException(\"The stream does not contain an ANI RIFF container.\");\n        }\n\n        uint declaredSize = BinaryPrimitives.ReadUInt32LittleEndian(riffHeader[4..]);\n        if (declaredSize < sizeof(uint))\n        {\n            throw new InvalidImageContentException(\"The ANI RIFF container size is invalid.\");\n        }\n\n        // RIFF size excludes the initial identifier and size field. Some real-world ANI files incorrectly\n        // include those eight bytes, so the physical stream length remains the hard read boundary.\n        long declaredEnd = checked(containerStart + 8 + declaredSize);\n        long containerEnd = Math.Min(declaredEnd, stream.Length);\n        bool headerFound = false;\n\n        while (stream.Position + AniConstants.ChunkHeaderSize <= containerEnd)\n        {\n            AniRiffChunkHeader chunk = this.ReadChunkHeader(stream);\n            long dataEnd = GetChunkDataEnd(stream, chunk.Size, containerEnd);\n\n            switch ((AniChunkType)chunk.FourCc)\n            {\n                case AniChunkType.Header:\n                    this.ReadAniHeader(stream, chunk.Size);\n                    headerFound = true;","sourceCodeStart":238,"sourceCodeEnd":274,"githubUrl":"https://github.com/SixLabors/ImageSharp/blob/59ce6af6fc29027cda277ef62d4d1694a8acce91/src/ImageSharp/Formats/Ani/AniDecoderCore.cs#L238-L274","documentation":"The RIFF chunk header declares a payload size, and this check requires it to be at least 4 bytes (the form-type field). A declared size below that cannot describe a valid RIFF form, so InvalidImageContentException is thrown. Note the decoder tolerates real-world files whose size incorrectly includes the 8-byte RIFF preamble — only absurdly small sizes fail here.","triggerScenarios":"Calling Decode/Identify on an ANI stream whose RIFF size field (bytes 4-8) is less than 4 — typically 0 or a garbage value from a corrupted or fabricated header.","commonSituations":"Files damaged by bit-rot or partial overwrite of the first sector; synthetic/fuzzed files; files produced by broken custom writers that emit a zero size field.","solutions":["Inspect bytes 4-8 of the file: fix or regenerate the RIFF size if you control the producing tool.","Re-export the ANI from source frames with a standard cursor authoring tool.","Restore the file from backup or re-download — header-level corruption is usually unrecoverable in place."],"exampleFix":"// before (header bytes): RIFF 00 00 00 00 ACON  (declaredSize=0)\n// after: patch the size to payload length\n// riffSize = (uint)(fileLength - 8); // 'ACON' + chunks","handlingStrategy":"validation","validationCode":"bool HasValidRiffSize(Stream s)\n{\n    byte[] h = new byte[8];\n    if (s.Read(h, 0, 8) != 8) return false;\n    s.Position = 0;\n    uint size = BinaryPrimitives.ReadUInt32LittleEndian(h.AsSpan(4, 4));\n    return size >= 4;\n}","typeGuard":null,"tryCatchPattern":"try\n{\n    using Image<Rgba32> img = Image.Load<Rgba32>(path);\n}\ncatch (InvalidImageContentException ex)\n{\n    logger.LogError(ex, \"ANI RIFF header corrupt.\");\n}","preventionTips":["Reject files with zero/garbage RIFF size fields at ingestion time.","Restore header-corrupted files from backups rather than patching by hand.","If you write RIFF containers, always set size = payload length (form type + chunks)."],"tags":["ani","riff","corrupt-file","image-decoding"],"backgroundTag":"invalid-image-content","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"}