{"record":{"id":"952b02501a9f1bf3","repo":"netty/netty","slug":"s-d-length-d-expected-range-0-d","errorCode":null,"errorMessage":"%s: %d, length: %d (expected: range(0, %d))","messagePattern":"(.+?): (.+?), length: (.+?) \\(expected: range\\(0, (.+?)\\)\\)","errorType":"exception","errorClass":"IndexOutOfBoundsException","httpStatus":null,"severity":"error","filePath":"buffer/src/main/java/io/netty/buffer/AbstractByteBuf.java","lineNumber":1417,"sourceCode":"    }\n\n    /**\n     * This is a simplified version of MathUtil.isOutOfBounds that does not check for capacity negative values.\n     */\n    private static boolean isOutOfBoundsTrustedCapacity(int index, int fieldLength, int capacity) {\n        // keep these as branches since would make it easier to be constant-folded\n        return index < 0 || fieldLength < 0 || index + fieldLength < 0 || index + fieldLength > capacity;\n    }\n\n    private static void checkRangeBounds(final String indexName, final int index,\n            final int fieldLength, final int capacity) {\n        if (isOutOfBounds(index, fieldLength, capacity)) {\n            rangeBoundsCheckFailed(indexName, index, fieldLength, capacity);\n        }\n    }\n\n    private static void rangeBoundsCheckFailed(String indexName, int index, int fieldLength, int capacity) {\n        throw new IndexOutOfBoundsException(String.format(\n                \"%s: %d, length: %d (expected: range(0, %d))\", indexName, index, fieldLength, capacity));\n    }\n\n    final void checkIndex0(int index, int fieldLength) {\n        if (checkBounds) {\n            checkRangeBoundsTrustedCapacity(\"index\", index, fieldLength, capacity());\n        }\n    }\n\n    protected final void checkSrcIndex(int index, int length, int srcIndex, int srcCapacity) {\n        checkIndex(index, length);\n        if (checkBounds) {\n            checkRangeBounds(\"srcIndex\", srcIndex, length, srcCapacity);\n        }\n    }\n\n    protected final void checkDstIndex(int index, int length, int dstIndex, int dstCapacity) {\n        checkIndex(index, length);","sourceCodeStart":1399,"sourceCodeEnd":1435,"githubUrl":"https://github.com/netty/netty/blob/70040aacae241e9ba371e758f5b86e470bd77ad1/buffer/src/main/java/io/netty/buffer/AbstractByteBuf.java#L1399-L1435","documentation":"Thrown by AbstractByteBuf.rangeBoundsCheckFailed via checkRangeBounds/isOutOfBounds (an IndexOutOfBoundsException). This is the generic workhorse for primitive and indexed get/set operations (e.g. checkIndex0, checkSrcType). isOutOfBounds is true when index < 0, fieldLength < 0, index + fieldLength < 0 (overflow), or index + fieldLength > capacity. indexName is usually 'index', so the message reads e.g. 'index: 5, length: 10 (expected: range(0, 100))'.","triggerScenarios":"Calling getInt/setInt/getBytes(index,...)/setBytes(index,...) and similar indexed accessors with a negative index, a negative length, an index+length that overflows int, or an index+length past capacity; reading a field at an offset computed from an attacker-controlled framing length.","commonSituations":"Decoding variable-length fields where the declared offset/length was not validated against the buffer; off-by-one in offset arithmetic (using capacity vs readableBytes); signed-length bug where a parsed length is negative.","solutions":["Validate against the correct bound: use readableBytes() for read-side offsets (index is relative to readerIndex) and capacity() for absolute set operations.","Sanitize parsed lengths: if (len < 0 || (long) idx + len > buf.capacity()) throw your own clearer error.","For derived offsets, prefer the read-flavored API (readInt/readBytes) which advances the cursor and bounds-checks against readable bytes automatically."],"exampleFix":"// before\nbuf.setInt(offset + 4, value); // offset + 4 + 4 > buf.capacity()\n\n// after\nint idx = offset + 4;\nif (idx < 0 || (long) idx + 4 > buf.capacity()) {\n    throw new DecoderException(\"header offset out of range: \" + idx);\n}\nbuf.setInt(idx, value);","handlingStrategy":"validation","validationCode":"// Validate absolute range before indexed get/set\nstatic void ensureRange(ByteBuf buf, int index, int len) {\n    if (index < 0 || len < 0 || (long) index + len > buf.capacity()) {\n        throw new IllegalArgumentException(\"bad range\");\n    }\n}\nensureRange(buf, idx, 4);\nbuf.setInt(idx, value);","typeGuard":"static boolean inRange(ByteBuf buf, int index, int len) {\n    return index >= 0 && len >= 0 && (long) index + len <= buf.capacity();\n}","tryCatchPattern":"try {\n    return buf.getInt(idx);\n} catch (IndexOutOfBoundsException e) {\n    throw new DecoderException(\"field offset \" + idx + \" out of range\", e);\n}","preventionTips":["Use readableBytes() for read-side offsets, capacity() for absolute set operations.","Sanitize parsed lengths against int overflow before indexing.","Prefer read-flavored accessors that auto-advance and check readable bytes."],"tags":["netty","bytebuf","index-bounds","get-set","decoder"],"backgroundTag":null,"analyzedSha":"70040aacae241e9ba371e758f5b86e470bd77ad1","analyzedAt":"2026-08-14T01:29:15.551Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}