{"record":{"id":"14ee50bd6b073117","repo":"github/copilot-sdk","slug":"invalid-off-len-for-buffer-of-length","errorCode":null,"errorMessage":"Invalid off/len for buffer of length ","messagePattern":"Invalid off/len for buffer of length ","errorType":"exception","errorClass":"IndexOutOfBoundsException","httpStatus":null,"severity":"error","filePath":"java/sdk/src/main/java/com/github/copilot/ffi/FfiOutputStream.java","lineNumber":39,"sourceCode":"\n    FfiOutputStream(NativeBinding nativeBinding, AtomicInteger connectionId, AtomicBoolean closing,\n            ReentrantLock operationLock) {\n        this.nativeBinding = Objects.requireNonNull(nativeBinding, \"nativeBinding must not be null\");\n        this.connectionId = Objects.requireNonNull(connectionId, \"connectionId must not be null\");\n        this.closing = Objects.requireNonNull(closing, \"closing must not be null\");\n        this.operationLock = Objects.requireNonNull(operationLock, \"operationLock must not be null\");\n    }\n\n    @Override\n    public void write(int b) throws IOException {\n        write(new byte[]{(byte) b}, 0, 1);\n    }\n\n    @Override\n    public void write(byte[] b, int off, int len) throws IOException {\n        Objects.requireNonNull(b, \"buffer must not be null\");\n        if (off < 0 || len < 0 || off + len > b.length) {\n            throw new IndexOutOfBoundsException(\"Invalid off/len for buffer of length \" + b.length);\n        }\n        if (len == 0) {\n            return;\n        }\n\n        operationLock.lock();\n        try {\n            if (closing.get()) {\n                throw new IOException(\"The in-process runtime connection is closed.\");\n            }\n            int id = connectionId.get();\n            if (id == 0) {\n                throw new IOException(\"The in-process runtime connection is closed.\");\n            }\n\n            byte[] payload = (off == 0 && len == b.length) ? b : Arrays.copyOfRange(b, off, off + len);\n            if (!nativeBinding.connectionWrite(id, payload, payload.length)) {\n                throw new IOException(\"Failed to write a frame to the in-process runtime connection.\");","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/github/copilot-sdk/blob/cd8cf15dc3f9e762615790aaed0a771a0f392755/java/sdk/src/main/java/com/github/copilot/ffi/FfiOutputStream.java#L21-L57","documentation":"FfiOutputStream.write(byte[], int, int) validates the offset/length pair against the buffer before forwarding bytes to the in-process runtime and throws IndexOutOfBoundsException for any out-of-range off/len. This is the standard OutputStream bounds contract: the sub-range [off, off+len) must lie entirely within b.","triggerScenarios":"Calling write(b, off, len) where off < 0, len < 0, or off + len > b.length — e.g., computing len from a miscounted remaining-bytes variable or passing a null-derived offset.","commonSituations":"Manual buffer slicing in streaming loops with off-by-one arithmetic; reusing a constant chunk size larger than the actual buffer; passing -1 as len from an EOF sentinel.","solutions":["Clamp off and len to 0..b.length before calling write","Use Arrays.copyOfRange or ByteBuffer to slice the buffer explicitly, then write the slice with off=0","Add an assertion or unit test covering boundary values (off=0, off=b.length, len=0)","Fix the arithmetic that computes remaining bytes (use b.length - off, not b.length - len)"],"exampleFix":"// before\nout.write(buf, off, buf.length); // ignores off\n// after\nout.write(buf, off, buf.length - off);","handlingStrategy":"validation","validationCode":"if (b == null || off < 0 || len < 0 || off + len > b.length) {\n    throw new IllegalArgumentException(\"bad off/len\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    out.write(buf, off, len);\n} catch (IndexOutOfBoundsException e) {\n    LOG.warning(\"dropping malformed chunk: \" + e.getMessage());\n}","preventionTips":["Compute len as b.length - off","Clamp ranges before writing","Unit-test boundary offsets","Prefer writing fully-sliced buffers with off=0"],"tags":["bounds","io","ffi","argument-validation"],"backgroundTag":"index-out-of-bounds","analyzedSha":"cd8cf15dc3f9e762615790aaed0a771a0f392755","analyzedAt":"2026-09-09T18:32:31.973Z","contentChangedAt":"2026-09-09T18:32:31.973Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}