MuntashirAkon/AppManager · error · IndexOutOfBoundsException

offs(" + offs + ") + len(" + len + ") > buf.length(" + buf.l

Error message

offs(" + offs + ") + len(" + len + ") > buf.length(" + buf.length + ").

What it means

write(byte[], int, int) checks offs + len against buf.length and throws IndexOutOfBoundsException if the requested range extends past the end of the array. The library refuses to read beyond the supplied buffer, per the OutputStream contract.

Source

Thrown at app/src/main/java/org/apache/commons/compress/compressors/bzip2/BZip2CompressorOutputStream.java:613

    /**
     * Returns the blocksize parameter specified at construction time.
     * @return the blocksize parameter specified at construction time
     */
    public final int getBlockSize() {
        return this.blockSize100k;
    }

    @Override
    public void write(final byte[] buf, int offs, final int len)
            throws IOException {
        if (offs < 0) {
            throw new IndexOutOfBoundsException("offs(" + offs + ") < 0.");
        }
        if (len < 0) {
            throw new IndexOutOfBoundsException("len(" + len + ") < 0.");
        }
        if (offs + len > buf.length) {
            throw new IndexOutOfBoundsException("offs(" + offs + ") + len("
                    + len + ") > buf.length("
                    + buf.length + ").");
        }
        if (closed) {
            throw new IOException("Stream closed");
        }

        for (final int hi = offs + len; offs < hi;) {
            write0(buf[offs++]);
        }
    }

    /**
     * Keeps track of the last bytes written and implicitly performs
     * run-length encoding as the first step of the bzip2 algorithm.
     */
    private void write0(int b) throws IOException {
        if (this.currentChar != -1) {

View on GitHub (pinned to 0152f468fc)

Solutions

  1. Recompute len as Math.min(len, buf.length - offs) before writing.
  2. Verify offs/len refer to the same buffer actually passed in.
  3. Add a debug assertion upstream that offs + len <= buf.length to catch the mismatch at its source.

Example fix

// before
out.write(buf, off, chunk);
// after
out.write(buf, off, Math.min(chunk, buf.length - off));
Defensive patterns

Strategy: validation

Validate before calling

if (offs < 0 || len < 0 || offs > buf.length - len) {
    throw new IllegalArgumentException("write range exceeds buffer: offs=" + offs + " len=" + len + " cap=" + buf.length);
}
out.write(buf, offs, len);

Try / catch

try {
    out.write(buf, offs, len);
} catch (IndexOutOfBoundsException e) {
    // clamp: out.write(buf, offs, Math.min(len, buf.length - offs));
}

Prevention

When it happens

Trigger: Calling write(buf, offs, len) with offs + len > buf.length — e.g. offs near the buffer end, or len counted from a different (larger) buffer.

Common situations: Mixing up buffer/offset pairs after reusing a smaller scratch buffer; forgetting to shrink len after a partial read; integer overflow of offs+len with huge offsets.

Related errors


AI-assisted analysis of MuntashirAkon/AppManager@0152f468fc (2026-09-12). Data as JSON: /api/errors/f6fa0faffa4ca9b4. Report an issue: GitHub.