{"record":{"id":"957be05cd6dbe6f6","repo":"HMCL-dev/HMCL","slug":"actl-chunk-length-must-be-d-not-d","errorCode":null,"errorMessage":"acTL chunk length must be %d, not %d","messagePattern":"acTL chunk length must be (.+?), not (.+?)","errorType":"exception","errorClass":"PngIntegrityException","httpStatus":null,"severity":"error","filePath":"HMCL/src/main/java/org/jackhuang/hmcl/ui/image/apng/reader/DefaultPngChunkReader.java","lineNumber":194,"sourceCode":"                // do nothing\n                source.skip(dataLength);\n                break;\n            case ANIMATED_KEEP_DEFAULT_IMAGE:\n                processor.processFrameImageData(source.slice(dataLength), PngChunkCode.IDAT, source.tell(), dataLength);\n                break;\n\n            case NOT_ANIMATED:\n            default:\n                processor.processDefaultImageData(source.slice(dataLength), PngChunkCode.IDAT, source.tell(), dataLength);\n                break;\n        }\n//        source.skip(dataLength);\n    }\n\n    @Override\n    public void readAnimationControlChunk(PngSource source, int dataLength) throws IOException, PngException {\n        if (dataLength != PngConstants.LENGTH_acTL_CHUNK) {\n            throw new PngIntegrityException(String.format(\"acTL chunk length must be %d, not %d\", PngConstants.LENGTH_acTL_CHUNK, dataLength));\n        }\n        processor.processAnimationControl(new PngAnimationControl(source.readInt(), source.readInt()));\n    }\n\n    @Override\n    public void readFrameControlChunk(PngSource source, int dataLength) throws IOException, PngException {\n        if (dataLength != PngConstants.LENGTH_fcTL_CHUNK) {\n            throw new PngIntegrityException(String.format(\"fcTL chunk length must be %d, not %d\", PngConstants.LENGTH_fcTL_CHUNK, dataLength));\n        }\n        int sequence = source.readInt(); // TODO: check sequence # is correct or PngIntegrityException\n\n        if (sequence != apngSequenceExpect) {\n            throw new PngIntegrityException(String.format(\"fctl chunk expected sequence %d but received %d\", apngSequenceExpect, sequence));\n        }\n        apngSequenceExpect++; // ready for next time\n\n        PngFrameControl frame = new PngFrameControl(\n                sequence,","sourceCodeStart":176,"sourceCodeEnd":212,"githubUrl":"https://github.com/HMCL-dev/HMCL/blob/24702dc5a0214034f4c27166d5fd30cad08cec19/HMCL/src/main/java/org/jackhuang/hmcl/ui/image/apng/reader/DefaultPngChunkReader.java#L176-L212","documentation":"This guard in readAnimationControlChunk fires when an acTL chunk's data length does not equal the exact size the APNG specification requires (8 bytes: num_frames plus num_plays). Any other length means the animation control chunk is malformed, so the animation metadata cannot be trusted.","triggerScenarios":"An APNG whose acTL chunk dataLength differs from 8, due to corruption, truncation, or a non-conformant APNG writer.","commonSituations":"Corrupted animated PNG downloads, files produced by experimental APNG encoders, misidentified chunk boundaries.","solutions":["Re-export the APNG with a compliant tool (e.g. ffmpeg -apng or apngasm).","Verify the file with an APNG-aware validator; confirm the acTL chunk length is 8.","If the file is not meant to be animated, check whether a wrong chunk is being read as acTL.","Catch PngIntegrityException and reject the malformed animation metadata."],"exampleFix":"// before\nreader.readAnimationControlChunk(source, dataLength);\n// after\nif (dataLength != 8) {\n    throw new PngIntegrityException(\"acTL must be 8 bytes, got \" + dataLength);\n}\nreader.readAnimationControlChunk(source, dataLength);","handlingStrategy":"try-catch","validationCode":"if (code == acTL && dataLength != 8) throw new IllegalStateException(\"acTL must be exactly 8 bytes\");","typeGuard":null,"tryCatchPattern":"try { reader.readAnimationControlChunk(source, dataLength); } catch (PngIntegrityException e) { failDecode(\"malformed acTL: \" + e.getMessage()); }","preventionTips":["Produce APNGs with compliant tools (apngasm, ffmpeg).","Validate acTL length == 8 during pre-scan.","Confirm the file is really an APNG before parsing animation chunks.","Handle PngIntegrityException to fall back to static first-frame rendering."],"tags":["png","apng","animation","validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"24702dc5a0214034f4c27166d5fd30cad08cec19","analyzedAt":"2026-09-10T12:36:46.680Z","contentChangedAt":"2026-09-10T12:36:46.680Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}