{"record":{"id":"f02c23d6ca708c61","repo":"Tencent/tinker","slug":"in-null","errorCode":null,"errorMessage":"in == null","messagePattern":"in == null","errorType":"exception","errorClass":"NullPointerException","httpStatus":null,"severity":"error","filePath":"third-party/tinker-ziputils/src/main/java/com/tencent/tinker/ziputils/ziputil/Streams.java","lineNumber":75,"sourceCode":"    /**\n     * Fills 'dst' with bytes from 'in', throwing EOFException if insufficient bytes are available.\n     */\n    public static void readFully(InputStream in, byte[] dst) throws IOException {\n        readFully(in, dst, 0, dst.length);\n    }\n\n    /**\n     * Reads exactly 'byteCount' bytes from 'in' (into 'dst' at offset 'offset'), and throws\n     * EOFException if insufficient bytes are available.\n     *\n     * Used to implement {@link java.io.DataInputStream#readFully(byte[], int, int)}.\n     */\n    public static void readFully(InputStream in, byte[] dst, int offset, int byteCount) throws IOException {\n        if (byteCount == 0) {\n            return;\n        }\n        if (in == null) {\n            throw new NullPointerException(\"in == null\");\n        }\n        if (dst == null) {\n            throw new NullPointerException(\"dst == null\");\n        }\n        Arrays.checkOffsetAndCount(dst.length, offset, byteCount);\n        while (byteCount > 0) {\n            int bytesRead = in.read(dst, offset, byteCount);\n            if (bytesRead < 0) {\n                throw new EOFException();\n            }\n            offset += bytesRead;\n            byteCount -= bytesRead;\n        }\n    }\n    /**\n     * Returns a byte[] containing the remainder of 'in', closing it when done.\n     */\n    public static byte[] readFully(InputStream in) throws IOException {","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/Tencent/tinker/blob/1b7ea02c239840f563ea64fb5bd286eb98d4011e/third-party/tinker-ziputils/src/main/java/com/tencent/tinker/ziputils/ziputil/Streams.java#L57-L93","documentation":"Streams.readFully(InputStream, byte[], int, int) is a strict replacement for DataInputStream.readFully: it validates its arguments before doing I/O. When byteCount > 0 and the supplied InputStream is null it throws NullPointerException(\"in == null\") — a programming-error guard, not an I/O condition, signaling the caller passed an unopened/failed stream reference.","triggerScenarios":"Any internal ziputils read path (TinkerZipEntry parsing, TinkerZipFile streaming) invoking Streams.readFully with a null InputStream — typically because a stream-open call earlier returned null after a caught exception instead of propagating.","commonSituations":"Wrapped stream factories that return null on failure (anti-pattern) feeding zip readers; fields initialized lazily that were never set because of an earlier error; test harnesses constructing parsers with null stream stubs.","solutions":["Ensure the InputStream is opened (non-null) before constructing readers that consume it; propagate open failures instead of null.","Change null-returning factory methods to throw the original IOException so the NPE never masks the root cause.","In tests, pass a real ByteArrayInputStream or a proper mock rather than null."],"exampleFix":"// before: factory returns null on failure, caller passes it on\nInputStream open(String name) {\n    try { return files.get(name); }\n    catch (IOException e) { return null; }\n}\nStreams.readFully(open(name), buf, 0, len); // NPE: in == null\n\n// after: propagate the failure\nInputStream open(String name) throws IOException {\n    return files.get(name);\n}\ntry (InputStream in = open(name)) {\n    Streams.readFully(in, buf, 0, len);\n}","handlingStrategy":"validation","validationCode":"// Ensure a non-null stream before parsing\njava.util.Objects.requireNonNull(in, \"input stream must be opened before reading\");\nStreams.readFully(in, dst, 0, len);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Open streams in try-with-resources so a failed open propagates instead of yielding null.","Never write factory methods that return null on error — throw.","Assert non-null at your API boundary with Objects.requireNonNull for clear failure context."],"tags":["zip","null-check","stream","tinker"],"backgroundTag":null,"analyzedSha":"1b7ea02c239840f563ea64fb5bd286eb98d4011e","analyzedAt":"2026-08-14T15:16:52.110Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}