{"record":{"id":"917597a970848cb3","repo":"pxb1988/dex2jar","slug":"file-too-short-to-be-a-zip-file","errorCode":null,"errorMessage":"File too short to be a zip file: ","messagePattern":"File too short to be a zip file: ","errorType":"exception","errorClass":"ZipException","httpStatus":null,"severity":"error","filePath":"dex-reader/src/main/java/com/googlecode/d2j/util/zip/ZipFile.java","lineNumber":193,"sourceCode":"     * \n     * <p>\n     * The central directory can be followed by a variable-length comment field, so we have to scan through it\n     * backwards. The comment is at most 64K, plus we have 18 bytes for the end-of-central-dir stuff itself, plus\n     * apparently sometimes people throw random junk on the end just for the fun of it.\n     * \n     * <p>\n     * This is all a little wobbly. If the wrong value ends up in the EOCD area, we're hosed. This appears to be the way\n     * that everybody handles it though, so we're in good company if this fails.\n     */\n    private void readCentralDir() throws IOException {\n        ByteBuffer raf = this.raf;\n        // Scan back, looking for the End Of Central Directory field. If the zip file doesn't\n        // have an overall comment (unrelated to any per-entry comments), we'll hit the EOCD\n        // on the first try.\n        // No need to synchronize raf here -- we only do this when we first open the zip file.\n        long scanOffset = raf.limit() - ENDHDR;\n        if (scanOffset < 0) {\n            throw new ZipException(\"File too short to be a zip file: \" + raf.limit());\n        }\n\n        // not check Magic\n        // raf.position(0);\n        // final int headerMagic = raf.getInt();\n        // if (headerMagic != LOCSIG) {\n        // throw new ZipException(\"Not a zip archive\");\n        // }\n\n        long stopOffset = scanOffset - 65536;\n        if (stopOffset < 0) {\n            stopOffset = 0;\n        }\n\n        while (true) {\n            raf.position((int) scanOffset);\n            if (raf.getInt() == ENDSIG) {\n                break;","sourceCodeStart":175,"sourceCodeEnd":211,"githubUrl":"https://github.com/pxb1988/dex2jar/blob/b5bda4fb4935ae8b3869b422454ae3b3896c7bc1/dex-reader/src/main/java/com/googlecode/d2j/util/zip/ZipFile.java#L175-L211","documentation":"ZipFile.readCentralDir (constructor) throws ZipException when the file is smaller than the 22-byte End Of Central Directory record (raf.limit() - ENDHDR < 0), meaning it cannot possibly be a zip archive.","triggerScenarios":"Opening an empty file, a partially downloaded zip, a truncated DEX-in-zip, or pointing ZipFile at a non-zip file shorter than 22 bytes.","commonSituations":"Failed/interrupted downloads, placeholder files created but never written, mounting the wrong path in build pipelines.","solutions":["Check file length >= 22 bytes before constructing ZipFile","Re-download or regenerate the zip file","Verify the path points to the real archive, not a stub or directory"],"exampleFix":"// before\nZipFile zip = new ZipFile(f);\n// after\nif (f.length() < 22) throw new IOException(\"not a zip: too small \" + f);\nZipFile zip = new ZipFile(f);","handlingStrategy":"validation","validationCode":"File f = new File(path);\nif (!f.isFile() || f.length() < 22) throw new IOException(\"too small to be a zip: \" + f);","typeGuard":"boolean isPlausibleZip(File f) { return f.isFile() && f.length() >= 22; }","tryCatchPattern":"try { ZipFile z = new ZipFile(f); } catch (ZipException e) { throw new IOException(\"not a valid zip: \" + f, e); }","preventionTips":["Check file size (> 22 bytes) and existence before opening","Detect failed downloads (zero-byte or partial files) early in pipelines","Verify the path points at the archive, not a placeholder or directory"],"tags":["zip","corrupt-file","file-size"],"backgroundTag":"file-not-found","analyzedSha":"b5bda4fb4935ae8b3869b422454ae3b3896c7bc1","analyzedAt":"2026-09-08T00:44:01.258Z","contentChangedAt":"2026-09-08T00:44:01.258Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}