HMCL-dev/HMCL · error · PngIntegrityException

Corrupted read (Data length )

Error message

Corrupted read (Data length %d)

What it means

This guard in DefaultPngChunkReader.readChunk fires when a chunk's declared data length cannot actually be read from the stream - fewer bytes are available than the length field promises. It indicates the PNG stream is truncated or the chunk table is corrupted, so the current chunk cannot be consumed.

Solutions

  1. Confirm the stream is positioned at a real chunk boundary (check the 8-byte PNG signature and IHDR alignment).
  2. Inspect the corrupted file with a PNG validator (pngcheck) to find where the stream desyncs.
  3. Re-download/re-export the image; the file bytes are damaged.
  4. Catch PngIntegrityException around chunk iteration to fail gracefully.

Example fix

// before
reader.readChunk(source, code, dataLength);
// after
if (dataLength < 0 || dataLength > maxChunkSize) {
    throw new PngIntegrityException("implausible chunk length " + dataLength);
}
reader.readChunk(source, code, dataLength);
Defensive patterns

Strategy: try-catch

Validate before calling

if (dataLength < 0 || dataLength > fileBytesRemaining) throw new IllegalStateException("corrupt chunk length");

Try / catch

try { while (reader.readChunk(source, code, len)) { ... } } catch (PngIntegrityException e) { abortDecode("corrupt stream: " + e.getMessage()); }

Prevention

When it happens

Trigger: A chunk length field (or prior misread) yields dataLength < 0, e.g. after seeking errors, wrong stream offset, or corrupted length bytes with the high bit set.

Common situations: Corrupted PNG files, reading from a misaligned stream, treating a non-PNG file as PNG.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10). Data as JSON: /api/errors/005654f744e3f0fa. Report an issue: GitHub.

Appendix: source

Thrown at HMCL/src/main/java/org/jackhuang/hmcl/ui/image/apng/reader/DefaultPngChunkReader.java:42

 */
public class DefaultPngChunkReader<ResultT> implements PngChunkReader<ResultT> {
    protected PngChunkProcessor<ResultT> processor;
    protected boolean seenHeader = false;
    protected int idatCount = 0;
    protected int apngSequenceExpect = 0;
    protected PngAnimationType animationType = PngAnimationType.NOT_ANIMATED;
    //private PngMainImageOp mainImageOp = PngMainImageOp.MAIN_IMAGE_KEEP;

    public DefaultPngChunkReader(PngChunkProcessor<ResultT> processor) {
        this.processor = processor;
    }

    @Override
    public boolean readChunk(PngSource source, int code, int dataLength) throws PngException, IOException {
        int dataPosition = source.tell(); // note the start position before any further reads are done.

        if (dataLength < 0) {
            throw new PngIntegrityException(String.format("Corrupted read (Data length %d)", dataLength));
        }

        switch (code) {
            case PngConstants.IHDR_VALUE:
                readHeaderChunk(source, dataLength);
                break;

            case PngConstants.IEND_VALUE:
                // NOP
                break;

            case PngConstants.gAMA_VALUE:
                readGammaChunk(source, dataLength);
                break;

            case PngConstants.bKGD_VALUE:
                readBackgroundChunk(source, dataLength);
                break;

View on GitHub (pinned to 24702dc5a0)