{"record":{"id":"b14b206f1f27bb91","repo":"Tencent/tinker","slug":"dst-null","errorCode":null,"errorMessage":"dst == null","messagePattern":"dst == 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":78,"sourceCode":"    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 {\n        try {\n            return readFullyNoClose(in);\n        } finally {","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/Tencent/tinker/blob/1b7ea02c239840f563ea64fb5bd286eb98d4011e/third-party/tinker-ziputils/src/main/java/com/tencent/tinker/ziputils/ziputil/Streams.java#L60-L96","documentation":"Argument-validation twin of the 'in == null' check in Streams.readFully: when the destination byte[] is null (and byteCount > 0), the method throws NullPointerException(\"dst == null\") before any read is attempted. It exists so callers get a clear programming-error message instead of an opaque NPE deep in the copy loop.","triggerScenarios":"Streams.readFully called with a null destination buffer — e.g. a buffer allocated conditionally (size read from a header) where the allocation was skipped or moved, or a field buffer nulled by a concurrent close/reset path.","commonSituations":"Header-driven allocation (`byte[] buf = len > 0 ? new byte[len] : null`) then readFully invoked unconditionally; buffer pooling that recycles arrays to null; race where one thread clears state while another still parses.","solutions":["Allocate the destination buffer before calling readFully, and handle the zero-length case via the byteCount == 0 early return rather than by nulling the array.","Keep parse state immutable per parse pass (local buffers, not shared nulled fields) to avoid races.","Add Objects.requireNonNull(dst) at your own API boundary to fail with your context, not the library's."],"exampleFix":"// before: null buffer for the empty case\nbyte[] extra = extraLen > 0 ? new byte[extraLen] : null;\nStreams.readFully(in, extra, 0, extraLen); // NPE when extraLen == 0 path misused\n\n// after: always allocate; rely on byteCount == 0 early return\nbyte[] extra = new byte[Math.max(0, extraLen)];\nif (extraLen > 0) {\n    Streams.readFully(in, extra, 0, extraLen);\n}","handlingStrategy":"validation","validationCode":"// Always allocate a destination buffer (zero-length handled by byteCount==0 early return)\nbyte[] dst = new byte[Math.max(0, count)];\nStreams.readFully(in, dst, 0, count);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Allocate buffers unconditionally; express 'nothing to read' via count==0, not a null array.","Use local (per-call) buffers instead of shared nulled fields to avoid races.","Require non-null buffers in your own APIs so the failure surfaces with your context."],"tags":["zip","null-check","buffer","tinker"],"backgroundTag":null,"analyzedSha":"1b7ea02c239840f563ea64fb5bd286eb98d4011e","analyzedAt":"2026-08-14T15:16:52.110Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}