{"record":{"id":"7d217c2d6527d0e7","repo":"oracle/graal","slug":"offset-s-length-s-array-length-s","errorCode":null,"errorMessage":"offset: %s, length: %s, array length: %s","messagePattern":"offset: (.+?), length: (.+?), array length: (.+?)","errorType":"exception","errorClass":"IndexOutOfBoundsException","httpStatus":null,"severity":"error","filePath":"compiler/src/jdk.graal.compiler.libgraal/src/jdk/graal/compiler/libgraal/truffle/BinaryOutput.java","lineNumber":587,"sourceCode":"         * Returns an address of an off-heap memory segment containing the marshalled data.\n         */\n        public CCharPointer getAddress() {\n            checkClosed();\n            return address;\n        }\n\n        @Override\n        public void write(int b) {\n            checkClosed();\n            ensureCapacity(pos + 1);\n            address.write(pos++, (byte) b);\n        }\n\n        @Override\n        public void write(byte[] b, int off, int len) {\n            checkClosed();\n            if ((off | len | b.length) < 0 || b.length - off < len) {\n                throw new IndexOutOfBoundsException(\"offset: \" + off + \", length: \" + len + \", array length: \" + b.length);\n            }\n            ensureCapacity(pos + len);\n            if (len > BYTEBUFFER_COPY_FROM_ARRAY_THRESHOLD) {\n                if (byteBufferView == null) {\n                    byteBufferView = CTypeConversion.asByteBuffer(address, length);\n                }\n                byteBufferView.position(pos);\n                byteBufferView.put(b, off, len);\n            } else {\n                for (int i = 0; i < len; i++) {\n                    address.write(pos + i, b[off + i]);\n                }\n            }\n            pos += len;\n        }\n\n        @Override\n        public void skip(int numberOfBytes) {","sourceCodeStart":569,"sourceCodeEnd":605,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/compiler/src/jdk.graal.compiler.libgraal/src/jdk/graal/compiler/libgraal/truffle/BinaryOutput.java#L569-L605","documentation":"The native-backed BinaryOutput.write(byte[], int, int) validates (off | len | b.length) < 0 || b.length - off < len and throws IndexOutOfBoundsException('offset: X, length: Y, array length: Z') — the same check as OutputStream.write semantics — before touching native memory. It protects the subsequent native address writes/ByteBuffer put from out-of-range source-array access.","triggerScenarios":"Calling write with negative off or len, off+len exceeding b.length, or a null-array edge producing b.length=0 with len>0 — usually from slicing bugs at the sender of the marshalled data.","commonSituations":"Substring/subarray slicing where end index exceeds the array; passing len from a protocol field without validating against the actual array size; off-by-one in chunked write loops.","solutions":["Validate off/len against b.length before the call: Objects.checkFromToIndex(off, off + len, b.length).","Derive len from the array itself when possible (len = b.length - off) instead of a separately tracked variable.","Fix the slicing arithmetic that produced off+len > b.length.","Add a debug assertion of (off, len, b.length) in your wrapper around the native output."],"exampleFix":"// before\nnativeOut.write(b, off, len);\n// after\nObjects.checkFromToIndex(off, off + len, b.length);\nnativeOut.write(b, off, len);","handlingStrategy":"validation","validationCode":"java.util.Objects.checkFromToIndex(off, off + len, b.length);\nnativeOut.write(b, off, len);","typeGuard":null,"tryCatchPattern":"try {\n    nativeOut.write(b, off, len);\n} catch (IndexOutOfBoundsException e) {\n    // message contains offset/length/array length: fix slicing at the call site\n}","preventionTips":["Use Objects.checkFromToIndex before writes","Derive len from the array (b.length - off) when possible","Watch off-by-one in chunked write loops"],"tags":["libgraal","truffle","marshalling","bounds","native-memory"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}