{"record":{"id":"83a8d059e472c91b","repo":"skylot/jadx","slug":"unexpected-size-of-decompressed-entry-entry-g","errorCode":null,"errorMessage":"Unexpected size of decompressed entry: ${entry}, got: ${written}, expected: ${out.length}","messagePattern":"Unexpected size of decompressed entry: (.+?), got: (.+?), expected: (.+?)","errorType":"exception","errorClass":"DataFormatException","httpStatus":null,"severity":"error","filePath":"jadx-commons/jadx-zip/src/main/java/jadx/zip/parser/ZipDeflate.java","lineNumber":27,"sourceCode":"import static jadx.zip.parser.JadxZipParser.bufferToStream;\n\nfinal class ZipDeflate {\n\tprivate static final int BUFFER_SIZE = 4096;\n\n\tstatic byte[] decompressEntryToBytes(ByteBuffer buf, JadxZipEntry entry) throws DataFormatException {\n\t\tbuf.position(entry.getDataStart());\n\t\tByteBuffer entryBuf = buf.slice();\n\t\tentryBuf.limit((int) entry.getCompressedSize());\n\t\tif (entry.getUncompressedSize() > Integer.MAX_VALUE) {\n\t\t\tthrow new DataFormatException(\"Entry too large: \" + entry.getUncompressedSize());\n\t\t}\n\t\tbyte[] out = new byte[(int) entry.getUncompressedSize()];\n\t\tInflater inflater = new Inflater(true);\n\t\tinflater.setInput(entryBuf);\n\t\tint written = inflater.inflate(out);\n\t\tinflater.end();\n\t\tif (written != out.length) {\n\t\t\tthrow new DataFormatException(\"Unexpected size of decompressed entry: \" + entry\n\t\t\t\t\t+ \", got: \" + written + \", expected: \" + out.length);\n\t\t}\n\t\treturn out;\n\t}\n\n\tstatic InputStream decompressEntryToStream(ByteBuffer buf, JadxZipEntry entry) {\n\t\tInputStream stream = bufferToStream(buf, entry.getDataStart(), (int) entry.getCompressedSize());\n\t\tInflater inflater = new Inflater(true);\n\t\treturn new InflaterInputStream(stream, inflater, BUFFER_SIZE);\n\t}\n}\n","sourceCodeStart":9,"sourceCodeEnd":39,"githubUrl":"https://github.com/skylot/jadx/blob/e738a26571d02919f01df40de93bc9a44dee4e18/jadx-commons/jadx-zip/src/main/java/jadx/zip/parser/ZipDeflate.java#L9-L39","documentation":"A data-integrity check in ZipDeflate. After inflating an entry's compressed payload into a buffer sized to the declared uncompressed size, jadx compares the number of bytes actually produced (inflater.inflate return value) against out.length (the declared size). A mismatch means the entry's size header is wrong or the data is corrupt, and a DataFormatException is thrown with got/expected counts. This guards against silent partial output.","triggerScenarios":"Decompressing a DEFLATE entry (compressMethod == 8) via ZipDeflate where Inflater.inflate() returns fewer bytes than entry.getUncompressedSize() (it never returns more because the output buffer is exactly that size). Reached during custom-parser entry reads and batch decompression.","commonSituations":"A tampered or truncated entry whose compressed data is shorter than declared; an obfuscator that lies about uncompressed size to confuse tools; a partially downloaded archive; a zip rebuilt incorrectly by merging tools.","solutions":["Inspect the got vs expected counts: a large gap usually means truncation; a small gap often means a bad size header.","Re-acquire the archive from a trusted source.","Allow jadx to fall back per-entry (do not set DONT_USE_FALLBACK) so the fallback parser can retry.","If repackaging, ensure the uncompressed-size field matches the real decompressed length."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// You cannot fully pre-validate without decompressing, but you can reject\n// entries whose declared uncompressed size is implausible.\nlong uncomp = entry.getUncompressedSize();\nif (uncomp < 0 || uncomp > MAX_ENTRY) {\n    throw new IOException(\"Implausible uncompressed size for \" + entry.getName());\n}","typeGuard":null,"tryCatchPattern":"try {\n    byte[] out = ZipDeflate.decompressEntry(buf, entry);\n} catch (java.util.zip.DataFormatException e) {\n    if (e.getMessage().contains(\"Unexpected size\")) {\n        LOG.warn(\"Size mismatch for entry {}, skipping\", entry);\n        continue;\n    }\n    throw e;\n}","preventionTips":["Treat a got/expected size mismatch as corruption; re-acquire the archive.","Keep the fallback enabled so per-entry failures can retry.","When repackaging, ensure uncompressed-size fields are accurate."],"tags":["zip","decompression","integrity","corrupted-archive"],"backgroundTag":null,"analyzedSha":"e738a26571d02919f01df40de93bc9a44dee4e18","analyzedAt":"2026-08-14T00:10:24.238Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}