{"record":{"id":"738e18a175b9b5e1","repo":"apache/dubbo","slug":"bytes2base64-offset-0-offset-is","errorCode":null,"errorMessage":"bytes2base64: offset < 0, offset is {}","messagePattern":"bytes2base64: offset < 0, offset is (.+?)","errorType":"exception","errorClass":"IndexOutOfBoundsException","httpStatus":null,"severity":"error","filePath":"dubbo-common/src/main/java/org/apache/dubbo/common/io/Bytes.java","lineNumber":528,"sourceCode":"     * @param code base64 code(0-63 is base64 char,64 is pad char).\n     * @return base64 string.\n     */\n    public static String bytes2base64(byte[] b, char[] code) {\n        return bytes2base64(b, 0, b.length, code);\n    }\n\n    /**\n     * to base64 string.\n     *\n     * @param bs   byte array.\n     * @param off  offset.\n     * @param len  length.\n     * @param code base64 code(0-63 is base64 char,64 is pad char).\n     * @return base64 string.\n     */\n    public static String bytes2base64(final byte[] bs, final int off, final int len, final char[] code) {\n        if (off < 0) {\n            throw new IndexOutOfBoundsException(\"bytes2base64: offset < 0, offset is \" + off);\n        }\n        if (len < 0) {\n            throw new IndexOutOfBoundsException(\"bytes2base64: length < 0, length is \" + len);\n        }\n        if (off + len > bs.length) {\n            throw new IndexOutOfBoundsException(\"bytes2base64: offset + length > array length.\");\n        }\n\n        if (code.length < 64) {\n            throw new IllegalArgumentException(\"Base64 code length < 64.\");\n        }\n\n        boolean pad = code.length > 64; // has pad char.\n        int num = len / 3, rem = len % 3, r = off, w = 0;\n        char[] cs = new char[num * 4 + (rem == 0 ? 0 : pad ? 4 : rem + 1)];\n\n        for (int i = 0; i < num; i++) {\n            int b1 = bs[r++] & MASK8, b2 = bs[r++] & MASK8, b3 = bs[r++] & MASK8;","sourceCodeStart":510,"sourceCodeEnd":546,"githubUrl":"https://github.com/apache/dubbo/blob/3a3043227f5571d25eb2889de5bca22f2914843b/dubbo-common/src/main/java/org/apache/dubbo/common/io/Bytes.java#L510-L546","documentation":"Thrown by Bytes.bytes2base64(byte[], int, int, char[] code) when the offset argument is negative. This is the first bounds check in the char[]-alphabet overload of base64 encoding; offset must be within [0, bs.length]. It prevents reading before the array start.","triggerScenarios":"Calling Bytes.bytes2base64(bs, off, len, code) with off < 0. Typically off is a computed/parsed index that was not validated for non-negativity.","commonSituations":"Negative offset from underflow in index arithmetic; a parsed offset field that yielded -1; a cursor decremented below zero; reusing an offset computed for a different buffer.","solutions":["Validate offset >= 0 before calling bytes2base64.","Use bytes2base64(byte[]) for the whole array to avoid manual offset.","Range-check the offset source at the parsing/computation boundary."],"exampleFix":"// before\nint off = cursor - 4; // may be negative\nString b64 = Bytes.bytes2base64(data, off, len, Bytes.BASE64.toCharArray()); // throws [159]\n\n// after\nif (off < 0 || off + len > data.length) throw new IllegalArgumentException();\nString b64 = Bytes.bytes2base64(data, off, len, Bytes.BASE64.toCharArray());","handlingStrategy":"validation","validationCode":"if (off < 0 || len < 0 || off + len > bs.length) {\n    throw new IllegalArgumentException(\"invalid range off=\" + off + \" len=\" + len + \" arr=\" + bs.length);\n}\nString b64 = Bytes.bytes2base64(bs, off, len, code);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use bytes2base64(byte[]) for full-array encoding.","Range-check offset/length at the boundary where they are computed.","Handle -1 sentinels explicitly rather than passing as offsets."],"tags":["bytes","base64","bounds-check","validation"],"backgroundTag":null,"analyzedSha":"3a3043227f5571d25eb2889de5bca22f2914843b","analyzedAt":"2026-08-14T00:43:19.853Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}