{"record":{"id":"42fd3fdea24190fa","repo":"apache/hadoop","slug":"offs-0","errorCode":null,"errorMessage":"offs({}) < 0.","messagePattern":"offs\\((.+?)\\) < 0\\.","errorType":"exception","errorClass":"IndexOutOfBoundsException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/compress/bzip2/CBZip2OutputStream.java","lineNumber":863,"sourceCode":"    bsPutUByte(0x90);\n\n    bsPutInt(this.combinedCRC);\n    bsFinishedWithStream();\n  }\n\n  /**\n  * Returns the blocksize parameter specified at construction time.\n  * @return blocksize.\n  */\n  public final int getBlockSize() {\n    return this.blockSize100k;\n  }\n\n  @Override\n  public void write(final byte[] buf, int offs, final int len)\n      throws IOException {\n    if (offs < 0) {\n      throw new IndexOutOfBoundsException(\"offs(\" + offs + \") < 0.\");\n    }\n    if (len < 0) {\n      throw new IndexOutOfBoundsException(\"len(\" + len + \") < 0.\");\n    }\n    if (offs + len > buf.length) {\n      throw new IndexOutOfBoundsException(\"offs(\" + offs + \") + len(\"\n          + len + \") > buf.length(\" + buf.length + \").\");\n    }\n    if (this.out == null) {\n      throw new IOException(\"stream closed\");\n    }\n\n    for (int hi = offs + len; offs < hi;) {\n      write0(buf[offs++]);\n    }\n  }\n\n  private void write0(int b) throws IOException {","sourceCodeStart":845,"sourceCodeEnd":881,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/compress/bzip2/CBZip2OutputStream.java#L845-L881","documentation":"CBZip2OutputStream.write(byte[], offs, len) validates its arguments before doing work. A negative offset yields IndexOutOfBoundsException(\"offs(...) < 0.\"). This mirrors the standard OutputStream contract: offsets before the array start are a caller bug and are rejected up front rather than reading out of bounds.","triggerScenarios":"write(buf, offs, len) with offs < 0: loop variables decremented past zero, a parsed offset like '-1' used as 'not found' sentinel, or arithmetic such as (pos - headerSize) going negative for small inputs.","commonSituations":"Sentinel -1 from indexOf/lastIndexOf flowing into an offset parameter; parsers computing offsets from user-supplied numbers without validation; refactors that swapped parameter order (offs/len) making a small length land in offs.","solutions":["Validate/normalize the offset before the call: if (offs < 0) throw new IllegalArgumentException(...) with the offending value.","Use java.util.Objects.checkFromToIndex(offs, offs + len, buf.length) once for all three bounds.","Fix the sentinel handling: never pass indexOf() results unchecked; map -1 to a skip/default path.","Add unit tests for boundary offsets (0, len, buf.length) on every OutputStream wrapper."],"exampleFix":"// before\ncbz.write(buf, offset, len); // offset == -1 from indexOf()\n\n// after\nint offset = src.indexOf(marker);\nif (offset < 0) {\n  return; // marker absent, nothing to write\n}\ncbz.write(buf, offset, len);","handlingStrategy":"validation","validationCode":"Objects.checkFromToIndex(offs, offs + len, buf.length); // throws before the codec does\ncbz.write(buf, offs, len);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never forward indexOf()-style -1 sentinels as offsets.","Centralize bounds checks with Objects.checkFromToIndex in wrappers.","Test boundary offsets 0, len, buf.length at every OutputStream layer."],"tags":["bzip2","compression","invalid-argument","bounds","hadoop"],"backgroundTag":"invalid-offset-length","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}