{"record":{"id":"f803db11d6b5dddc","repo":"Tencent/tinker","slug":"stored-entry-missing-size","errorCode":null,"errorMessage":"STORED entry missing size","messagePattern":"STORED entry missing size","errorType":"exception","errorClass":"ZipException","httpStatus":null,"severity":"error","filePath":"third-party/tinker-ziputils/src/main/java/com/tencent/tinker/ziputils/ziputil/TinkerZipOutputStream.java","lineNumber":464,"sourceCode":"            closeEntry();\n        }\n        // Did this ZipEntry specify a method, or should we use the default?\n        int method = ze.getMethod();\n        if (method == -1) {\n            method = defaultCompressionMethod;\n        }\n        // If the method is STORED, check that the ZipEntry was configured appropriately.\n        if (method == STORED) {\n            if (ze.getCompressedSize() == -1) {\n                ze.setCompressedSize(ze.getSize());\n            } else if (ze.getSize() == -1) {\n                ze.setSize(ze.getCompressedSize());\n            }\n            if (ze.getCrc() == -1) {\n                throw new ZipException(\"STORED entry missing CRC\");\n            }\n            if (ze.getSize() == -1) {\n                throw new ZipException(\"STORED entry missing size\");\n            }\n            if (ze.size != ze.compressedSize) {\n                throw new ZipException(\"STORED entry size/compressed size mismatch\");\n            }\n        }\n        checkOpen();\n        // checkAndSetZip64Requirements(ze);\n\n        //zhangshaowen edit here, we just want the same time and modDate\n        ze.comment = null;\n        ze.extra = null;\n        ze.time = TIME_CONST;\n        ze.modDate = MOD_DATE_CONST;\n\n        nameBytes = ze.name.getBytes(StandardCharsets.UTF_8);\n        checkSizeIsWithinShort(\"Name\", nameBytes);\n        entryCommentBytes = BYTE;\n        if (ze.comment != null) {","sourceCodeStart":446,"sourceCodeEnd":482,"githubUrl":"https://github.com/Tencent/tinker/blob/1b7ea02c239840f563ea64fb5bd286eb98d4011e/third-party/tinker-ziputils/src/main/java/com/tencent/tinker/ziputils/ziputil/TinkerZipOutputStream.java#L446-L482","documentation":"For STORED entries the uncompressed and compressed sizes must be known before data is written. putNextEntry() first tries to derive one from the other (if compressedSize == -1 it copies size, and vice versa); if BOTH size and compressedSize are still -1 it throws ZipException(\"STORED entry missing size\"). Unlike DEFLATED, STORED data is written verbatim so sizes cannot be discovered while streaming.","triggerScenarios":"putNextEntry(entry) with method STORED where neither entry.setSize(...) nor entry.setCompressedSize(...) was ever called — both remain at their -1 default after the derivation block runs.","commonSituations":"Streaming a dynamically generated file (unknown length) into a STORED entry; converting a DEFLATED pipeline to STORED and only setting the CRC but not sizes; copying entries from a source zip whose size fields were not read/populated.","solutions":["Buffer the entry data (byte[] or temp file) so its length is known, then call ze.setSize(len) and ze.setCompressedSize(len) before putNextEntry().","If the data is copied from another zip entry, copy the source entry's size and compressedSize fields across along with crc.","Switch the entry to DEFLATED if the length genuinely cannot be known up front."],"exampleFix":"// before\nTinkerZipEntry e = new TinkerZipEntry(\"assets/blob.bin\");\ne.setMethod(TinkerZipEntry.STORED);\ne.setCrc(crc32);\nzos.putNextEntry(e); // throws: missing size\n\n// after\nTinkerZipEntry e = new TinkerZipEntry(\"assets/blob.bin\");\ne.setMethod(TinkerZipEntry.STORED);\ne.setCrc(crc32);\ne.setSize(dataLen);\ne.setCompressedSize(dataLen);\nzos.putNextEntry(e);","handlingStrategy":"validation","validationCode":"void putStored(TinkerZipOutputStream zos, String name, byte[] data) throws IOException {\n    CRC32 crc = new CRC32();\n    crc.update(data);\n    TinkerZipEntry e = new TinkerZipEntry(name);\n    e.setMethod(TinkerZipEntry.STORED);\n    e.setCrc(crc.getValue());\n    e.setSize(data.length);\n    e.setCompressedSize(data.length);\n    zos.putNextEntry(e);\n    zos.write(data, 0, data.length);\n    zos.closeEntry();\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Buffer unknown-length data (memory or temp file) before writing STORED entries","Set size and compressedSize from the same length variable"],"tags":["zip","java","tinker","stored-entry","size"],"backgroundTag":null,"analyzedSha":"1b7ea02c239840f563ea64fb5bd286eb98d4011e","analyzedAt":"2026-08-14T15:16:52.110Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}