{"record":{"id":"6afdc0824c1ec2ab","repo":"apache/dubbo","slug":"hex2bytes-length-0-length-is","errorCode":null,"errorMessage":"hex2bytes: length < 0, length is {}","messagePattern":"hex2bytes: length < 0, length is (.+?)","errorType":"exception","errorClass":"IndexOutOfBoundsException","httpStatus":null,"severity":"error","filePath":"dubbo-common/src/main/java/org/apache/dubbo/common/io/Bytes.java","lineNumber":446,"sourceCode":"\n    /**\n     * from hex string.\n     *\n     * @param str hex string.\n     * @param off offset.\n     * @param len length.\n     * @return byte array.\n     */\n    public static byte[] hex2bytes(final String str, final int off, int len) {\n        if ((len & 1) == 1) {\n            throw new IllegalArgumentException(\"hex2bytes: ( len & 1 ) == 1.\");\n        }\n\n        if (off < 0) {\n            throw new IndexOutOfBoundsException(\"hex2bytes: offset < 0, offset is \" + off);\n        }\n        if (len < 0) {\n            throw new IndexOutOfBoundsException(\"hex2bytes: length < 0, length is \" + len);\n        }\n        if (off + len > str.length()) {\n            throw new IndexOutOfBoundsException(\"hex2bytes: offset + length > array length.\");\n        }\n\n        int num = len / 2, r = off, w = 0;\n        byte[] b = new byte[num];\n        for (int i = 0; i < num; i++) {\n            b[w++] = (byte) (hex(str.charAt(r++)) << 4 | hex(str.charAt(r++)));\n        }\n        return b;\n    }\n\n    /**\n     * to base64 string.\n     *\n     * @param b byte array.\n     * @return base64 string.","sourceCodeStart":428,"sourceCodeEnd":464,"githubUrl":"https://github.com/apache/dubbo/blob/3a3043227f5571d25eb2889de5bca22f2914843b/dubbo-common/src/main/java/org/apache/dubbo/common/io/Bytes.java#L428-L464","documentation":"Thrown by Bytes.hex2bytes(String, int, int) when the length argument is negative. The conversion reads len characters and produces len/2 bytes; a negative length is rejected after the even-length and offset checks. It guards against allocating a negative-sized array or looping incorrectly.","triggerScenarios":"Calling Bytes.hex2bytes(str, off, len) with len < 0. Common when len is derived from (end - start) with end < start, or an uninitialized/parsed length that is negative.","commonSituations":"Length from a corrupt protocol field; arithmetic producing a negative difference; default sentinel -1 for 'unset' passed through unchecked.","solutions":["Validate length >= 0 before calling hex2bytes.","Use hex2bytes(String) to avoid manual length computation.","Sanitize untrusted length inputs at the parse boundary."],"exampleFix":"// before\nint len = end - start; // negative if end < start\nbyte[] b = Bytes.hex2bytes(hex, off, len); // throws [156]\n\n// after\nint len = Math.max(0, end - start);\nbyte[] b = Bytes.hex2bytes(hex, off, len);","handlingStrategy":"validation","validationCode":"if (len < 0) throw new IllegalArgumentException(\"negative length: \" + len);\nbyte[] b = Bytes.hex2bytes(str, off, len);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Clamp computed lengths with Math.max(0, end - start).","Use hex2bytes(String) for the whole string.","Sanitize untrusted length inputs at the parse boundary."],"tags":["bytes","hex","bounds-check","validation"],"backgroundTag":null,"analyzedSha":"3a3043227f5571d25eb2889de5bca22f2914843b","analyzedAt":"2026-08-14T00:43:19.853Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}