Tencent/tinker · info · IOException

Size mismatch on inflated file

Error message

Size mismatch on inflated file: ${bytesRead} vs ${entry.size}

What it means

IOException('Size mismatch on inflated file: <bytesRead> vs <entry.size>') also lives inside the commented-out ZipInflaterInputStream class (TinkerZipFile.java:569 onward) and is unreachable in this fork. Its original purpose: when the inflater reports EOF, compare the number of bytes actually inflated (bytesRead) with the uncompressed size recorded in the entry's metadata (entry.size); a mismatch means either the deflate stream or the size field is wrong. In the live code of this repository it can never be thrown.

Solutions

  1. If hit on an AOSP-derived build: verify whether the deflate stream or the size field is wrong (inflate fully with an independent tool); usually the archive must be regenerated.
  2. Ensure any tool that rewrites entry contents also updates size/crc in the central directory and local headers.
  3. In this repository, no handling needed — dead code.
Defensive patterns

Strategy: try-catch

Try / catch

// only relevant on builds where ZipInflaterInputStream is enabled (not this fork)
try {
    readFully(in, expectedSize);
} catch (IOException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("Size mismatch on inflated file")) {
        // metadata disagrees with actual inflated bytes — archive is inconsistent
        throw new IOException("Entry size metadata does not match data; rebuild archive", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: In builds where the class is active: reading an entry whose DEFLATE stream ends at a different byte count than the central directory's uncompressed-size field — truncated data, an entry recompressed without updating sizes, or a tampered size field. In this repository: unreachable.

Common situations: Hot-patch/zip-flushing tools that rewrite entry data but keep stale size metadata; partially downloaded archives; auditing logs from a build derived from AOSP's zip implementation.

Related errors


AI-assisted analysis of Tencent/tinker@1b7ea02c23 (2026-08-14). Data as JSON: /api/errors/3bc68e68f6fd9312. Report an issue: GitHub.

Appendix: source

Thrown at third-party/tinker-ziputils/src/main/java/com/tencent/tinker/ziputils/ziputil/TinkerZipFile.java:586

    /** @hide */
    /*public static class ZipInflaterInputStream extends InflaterInputStream {
        private final ZipEntry entry;
        private long bytesRead = 0;
        public ZipInflaterInputStream(InputStream is, Inflater inf, int bsize, ZipEntry entry) {
            super(is, inf, bsize);
            this.entry = entry;
        }
        @Override public int read(byte[] buffer, int byteOffset, int byteCount) throws IOException {
            final int i;
            try {
                i = super.read(buffer, byteOffset, byteCount);
            } catch (IOException e) {
                throw new IOException("Error reading data for " + entry.getName() + " near offset "
                        + bytesRead, e);
            }
            if (i == -1) {
                if (entry.size != bytesRead) {
                    throw new IOException("Size mismatch on inflated file: " + bytesRead + " vs "
                            + entry.size);
                }
            } else {
                bytesRead += i;
            }
            return i;
        }
        @Override public int available() throws IOException {
            if (closed) {
                // Our superclass will throw an exception, but there's a jtreg test that
                // explicitly checks that the InputStream returned from ZipFile.getInputStream
                // returns 0 even when closed.
                return 0;
            }
            return super.available() == 0 ? 0 : (int) (entry.getSize() - bytesRead);
        }
    }*/
}

View on GitHub (pinned to 1b7ea02c23)