{"record":{"id":"3797c39d5de24de3","repo":"apache/hadoop","slug":"write-b","errorCode":null,"errorMessage":"write (b[{}], {}, {})","messagePattern":"write \\(b\\[(.+?)\\], (.+?), (.+?)\\)","errorType":"validation","errorClass":"IndexOutOfBoundsException","httpStatus":null,"severity":"error","filePath":"hadoop-cloud-storage-project/hadoop-huaweicloud/src/main/java/org/apache/hadoop/fs/obs/OBSDataBlocks.java","lineNumber":75,"sourceCode":"  private OBSDataBlocks() {\n  }\n\n  /**\n   * Validate args to a write command. These are the same validation checks\n   * expected for any implementation of {@code OutputStream.write()}.\n   *\n   * @param b   byte array containing data\n   * @param off offset in array where to start\n   * @param len number of bytes to be written\n   * @throws NullPointerException      for a null buffer\n   * @throws IndexOutOfBoundsException if indices are out of range\n   */\n  static void validateWriteArgs(final byte[] b, final int off,\n      final int len) {\n    Preconditions.checkNotNull(b);\n    if (off < 0 || off > b.length || len < 0 || off + len > b.length\n        || off + len < 0) {\n      throw new IndexOutOfBoundsException(\n          \"write (b[\" + b.length + \"], \" + off + \", \" + len + ')');\n    }\n  }\n\n  /**\n   * Create a factory.\n   *\n   * @param owner factory owner\n   * @param name  factory name -the option from {@link OBSConstants}.\n   * @return the factory, ready to be initialized.\n   * @throws IllegalArgumentException if the name is unknown.\n   */\n  static BlockFactory createFactory(final OBSFileSystem owner,\n      final String name) {\n    switch (name) {\n    case OBSConstants.FAST_UPLOAD_BUFFER_ARRAY:\n      return new ByteArrayBlockFactory(owner);\n    case OBSConstants.FAST_UPLOAD_BUFFER_DISK:","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-cloud-storage-project/hadoop-huaweicloud/src/main/java/org/apache/hadoop/fs/obs/OBSDataBlocks.java#L57-L93","documentation":"OBSDataBlocks.validateWriteArgs(b, off, len) is the bounds check called at the top of OBSBlockOutputStream.write and elsewhere: after Preconditions.checkNotNull(b), it rejects off<0, len<0, off>b.length, off+len>b.length, or integer-overflow off+len<0 with IndexOutOfBoundsException('write (b[<len>], <off>, <len>)'). The message is the full call signature, letting you immediately see which argument is inconsistent with the buffer size. This is a pure caller bug — the buffer slice described does not exist.","triggerScenarios":"Passing offset/len computed from a previous, different buffer; len larger than remaining bytes (off+len>b.length) after arithmetic mistakes; negative offset from a read() that returned -1 and was fed into offset; Integer overflow when off+len wraps around (huge len near Integer.MAX_VALUE); reusing a loop variable as offset without resetting it.","commonSituations":"Custom InputStream/OutputStream adapters translating between stream APIs; compression or crypto wrappers computing chunk offsets; loops like 'off += read(); write(b, off, len)' that forget read() can return -1; copy helpers mixing up (srcPos, length) argument order.","solutions":["Fix the caller's arithmetic: assert 0 <= off && off + len <= b.length before calling write; treat read()==-1 as EOS instead of an offset.","Use System.arraycopy semantics or Arrays.copyOfRange(b, off, off+len) when you need a safe slice.","Reset loop offsets at buffer boundaries; prefer 'while ((n = in.read(buf)) != -1) out.write(buf, 0, n);' which is inherently safe.","For chunked writers, compute len as Math.min(chunkSize, remaining) rather than trusting passed-in sizes."],"exampleFix":"// before\nint off = in.read(prevBuf);            // can be -1 at EOF\nout.write(buf, off, len);              // -> write (b[8192], -1, 4096)\n\n// after\nint n;\nwhile ((n = in.read(buf)) != -1) {\n  out.write(buf, 0, n);                // offsets always valid\n}","handlingStrategy":"validation","validationCode":"static void checkWriteArgs(byte[] b, int off, int len) {\n  java.util.Objects.requireNonNull(b);\n  if (off < 0 || len < 0 || off > b.length || len > b.length - off) {\n    throw new IndexOutOfBoundsException(\n        \"write(b[\" + b.length + \"], \" + off + \", \" + len + \")\");\n  }\n}\ncheckWriteArgs(buf, off, len); out.write(buf, off, len);","typeGuard":null,"tryCatchPattern":"try {\n  out.write(buf, off, len);\n} catch (IndexOutOfBoundsException e) {\n  if (String.valueOf(e.getMessage()).startsWith(\"write (b[\")) {\n    throw new IllegalArgumentException(\"bad (off,len) for buffer — caller bug\", e);\n  }\n  throw e;\n}","preventionTips":["Use the canonical copy loop: while ((n = in.read(buf)) != -1) out.write(buf, 0, n).","Never feed a read() return value into offset without checking for -1.","Compute len as Math.min(chunk, b.length - off).","Note the message format 'write (b[len], off, len)' reports buffer LENGTH first — use it to spot the mismatch."],"tags":["obs","huaweicloud","index-out-of-bounds","buffer-math","api-misuse"],"backgroundTag":"index-out-of-bounds","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}