{"record":{"id":"d7c3ccffa2a4c400","repo":"eclipse-vertx/vert.x","slug":"index-size-length","errorCode":null,"errorMessage":"<index> + <size> > <length>","messagePattern":"<index> \\+ <size> > <length>","errorType":"exception","errorClass":"IndexOutOfBoundsException","httpStatus":null,"severity":"error","filePath":"vertx-core/src/main/java/io/vertx/core/buffer/impl/BufferImpl.java","lineNumber":199,"sourceCode":"  public int getMediumLE(int pos) {\n    checkUpperBound(pos, 3);\n    return buffer.getMediumLE(pos);\n  }\n\n  public int getUnsignedMedium(int pos) {\n    checkUpperBound(pos, 3);\n    return buffer.getUnsignedMedium(pos);\n  }\n\n  public int getUnsignedMediumLE(int pos) {\n    checkUpperBound(pos, 3);\n    return buffer.getUnsignedMediumLE(pos);\n  }\n\n  private void checkUpperBound(int index, int size) {\n    int length = buffer.writerIndex();\n    if (index < 0 || index + size < 0 || index + size > length) {\n      throw new IndexOutOfBoundsException(index + \" + \" + size + \" > \" + length);\n    }\n  }\n\n  public byte[] getBytes() {\n    byte[] arr = new byte[buffer.writerIndex()];\n    buffer.getBytes(0, arr);\n    return arr;\n  }\n\n  public byte[] getBytes(int start, int end) {\n    Arguments.require(end >= start, \"end must be greater or equal than start\");\n    byte[] arr = new byte[end - start];\n    buffer.getBytes(start, arr, 0, end - start);\n    return arr;\n  }\n\n  @Override\n  public Buffer getBytes(byte[] dst) {","sourceCodeStart":181,"sourceCodeEnd":217,"githubUrl":"https://github.com/eclipse-vertx/vert.x/blob/fb308bd8c3f12c79f4ae89bef67fadf6c80d036e/vertx-core/src/main/java/io/vertx/core/buffer/impl/BufferImpl.java#L181-L217","documentation":"BufferImpl.checkUpperBound throws IndexOutOfBoundsException with a message of the form \"<index> + <size> > <length>\" when a read primitive (getByte, getUnsignedByte, getInt, getIntLE, getUnsignedInt, getUnsignedIntLE, etc.) would access bytes beyond the buffer's writer index (its logical length), or when index/size arithmetic overflows to negative. This mirrors Netty's bounds checking: Buffers are length-bounded views over Netty buffers, and reading past the written data is an error rather than a zero-fill.","triggerScenarios":"buffer.getByte(i) with i >= buffer.length(); getInt(i) where i+4 exceeds length(); calls after the buffer was reset/truncated to a smaller size; negative index; or index+size overflowing int range with a huge index near Integer.MAX_VALUE.","commonSituations":"Parsing binary protocols with off-by-one or unvalidated length fields; reusing a buffer index computed for a previous (larger) packet; assuming get* zero-pads beyond the end like an array might; reading fixed-width fields at a variable offset without checking remaining bytes.","solutions":["Check bounds before reading: if (index + fieldSize > buffer.length()) handle/throw a descriptive parse error.","Verify the buffer actually contains the expected bytes (e.g. from a truncated network read) before parsing.","Fix the index computation so it never goes negative or overflows (use long arithmetic for the sum if indices can be large)."],"exampleFix":"// before\nint value = buffer.getInt(offset); // throws if offset+4 > buffer.length()\n// after\nif (offset < 0 || offset + 4 > buffer.length()) {\n  throw new IllegalStateException(\"truncated buffer: need \" + (offset + 4) + \" bytes, have \" + buffer.length());\n}\nint value = buffer.getInt(offset);","handlingStrategy":"validation","validationCode":"static void requireBytes(io.vertx.core.buffer.Buffer b, int index, int size) {\n  if (index < 0 || index + size > b.length())\n    throw new IllegalStateException(\"need bytes [\" + index + \",\" + (index + size) + \") but buffer length is \" + b.length());\n}","typeGuard":"static boolean hasBytes(io.vertx.core.buffer.Buffer b, int index, int size) {\n  return index >= 0 && size >= 0 && (long) index + size <= b.length();\n}","tryCatchPattern":"try {\n  int v = buffer.getInt(offset);\n  parse(v);\n} catch (IndexOutOfBoundsException e) {\n  throw new ProtocolParseException(\"truncated frame at offset \" + offset + \": \" + e.getMessage(), e);\n}","preventionTips":["Check buffer.length() before every variable-offset fixed-width read","Validate protocol length fields against remaining bytes before parsing","Track remaining = length - offset and refuse to read when remaining < fieldSize"],"tags":["vertx","buffer","bounds-check","binary-parsing"],"backgroundTag":"index-out-of-bounds","analyzedSha":"fb308bd8c3f12c79f4ae89bef67fadf6c80d036e","analyzedAt":"2026-09-06T11:37:12.241Z","contentChangedAt":"2026-09-06T11:37:12.241Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}