{"record":{"id":"433f70cb23a86aff","repo":"java-native-access/jna","slug":"bounds-exceeds-available-space-size-size-offset-off-sz","errorCode":null,"errorMessage":"Bounds exceeds available space : size=<size>, offset=<off+sz>","messagePattern":"Bounds exceeds available space : size=<size>, offset=<off\\+sz>","errorType":"validation","errorClass":"IndexOutOfBoundsException","httpStatus":null,"severity":"error","filePath":"src/com/sun/jna/Memory.java","lineNumber":224,"sourceCode":"    }\n\n    public long size() {\n        return size;\n    }\n\n    /**\n     * Check that indirection won't cause us to write outside the\n     * malloc'ed space.\n     *\n     */\n    protected void boundsCheck(long off, long sz) {\n        if (off < 0) {\n            throw new IndexOutOfBoundsException(\"Invalid offset: \" + off);\n        }\n        if (off + sz > size) {\n            String msg = \"Bounds exceeds available space : size=\"\n                + size + \", offset=\" + (off + sz);\n            throw new IndexOutOfBoundsException(msg);\n        }\n    }\n\n    //////////////////////////////////////////////////////////////////////////\n    // Raw read methods\n    //////////////////////////////////////////////////////////////////////////\n\n    /**\n     * Indirect the native pointer to <code>malloc</code> space, a la\n     * <code>Pointer.read</code>.  But this method performs a bounds\n     * checks to ensure that the indirection does not cause memory outside the\n     * <code>malloc</code>ed space to be accessed.\n     *\n     * @see Pointer#read(long,byte[],int,int)\n     */\n    @Override\n    public void read(long bOff, byte[] buf, int index, int length) {\n        boundsCheck(bOff, length * 1L);","sourceCodeStart":206,"sourceCodeEnd":242,"githubUrl":"https://github.com/java-native-access/jna/blob/d036ad9781adad4b66693e8fa7098e4ac665e0a3/src/com/sun/jna/Memory.java#L206-L242","documentation":"Memory.boundsCheck() also verifies that offset+requested-size stays within this Memory block's allocated size. When off + sz > size, the access would write/read outside the malloc'ed space, so JNA throws IndexOutOfBoundsException with the block size and the offending end offset.","triggerScenarios":"Any Memory accessor whose offset plus access size exceeds the block: e.g. new Memory(8).readLong(4), read(0, buf, 0, 16) on a 8-byte block, setString near the end with a string longer than remaining space, or using a share() slice and indexing beyond the slice.","commonSituations":"Reading C arrays/structs with wrong element size or count; assuming a buffer is larger than it is after Memory.share; off-by-one in loops copying data; wrong struct size after a native API change.","solutions":["Increase the allocated size: new Memory(requiredSize) with size >= off + sz.","Compute sizes from the actual data (STRUCTURE.SIZE, array lengths) rather than hardcoded constants.","Clamp or validate length before access: assert off + sz <= memory.size().","Re-share the full backing Memory with the correct offset/size instead of over-reading a slice."],"exampleFix":"// before\nMemory mem = new Memory(8);\nmem.read(0, buf, 0, 16); // throws: 16 > 8\n// after\nMemory mem = new Memory(buf.length); // size matches the data\nmem.read(0, buf, 0, buf.length);","handlingStrategy":"validation","validationCode":"long end = offset + requestedBytes;\nif (end > memory.size()) {\n    throw new IllegalArgumentException(\"read of \" + requestedBytes + \" at \" + offset + \" exceeds size \" + memory.size());\n}\nmemory.read(offset, buffer, 0, requestedBytes);","typeGuard":"boolean fitsIn(Memory m, long off, long sz) {\n    return off >= 0 && sz >= 0 && off + sz <= m.size();\n}","tryCatchPattern":"try {\n    memory.read(offset, buffer, 0, len);\n} catch (IndexOutOfBoundsException e) {\n    // grow or clamp\n    memory = new Memory(offset + len);\n    memory.read(offset, buffer, 0, len);\n}","preventionTips":["Size Memory blocks from Structure.SIZE or explicit array counts, never magic numbers.","Track share() slice sizes separately from the backing buffer's size.","Add bounds assertions (fitsIn) before bulk read/write loops to catch off-by-one early."],"tags":["jna","native-memory","buffer-overflow","bounds-check"],"backgroundTag":"index-out-of-range","analyzedSha":"d036ad9781adad4b66693e8fa7098e4ac665e0a3","analyzedAt":"2026-09-12T06:50:59.239Z","contentChangedAt":"2026-09-12T06:50:59.239Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}