MuntashirAkon/AppManager · error · IndexOutOfBoundsException

offs(" + offs + ") < 0.

Error message

offs(" + offs + ") < 0.

What it means

write(byte[] buf, int offs, int len) validates its arguments per the OutputStream contract: negative offsets, negative lengths, or offs+len beyond the buffer throw IndexOutOfBoundsException. These are caller bugs, not stream-state issues.

Source

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

        bsPutUByte(0x90);

        bsPutInt(this.combinedCRC);
        bsFinishedWithStream();
    }

    /**
     * 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++]);
        }
    }

View on GitHub (pinned to 0152f468fc)

Solutions

  1. Fix the offset arithmetic so offs >= 0 and offs + len <= buf.length.
  2. Check upstream read()/position results for -1 (EOF) before passing them as len.
  3. Use safer helpers (e.g. buf, 0, n from InputStream.read) instead of hand-rolled offsets.
  4. Optionally validate arguments with Objects.checkFromIndexRange-style checks before calling.

Example fix

// before
int n = in.read(buf);
compressor.write(buf, offs, n); // offs can be -1 / stale
// after
int n = in.read(buf);
if (n > 0) compressor.write(buf, 0, n);
Defensive patterns

Strategy: validation

Validate before calling

// standard bounds check before writing
if (offs < 0 || len < 0 || offs + len > buf.length)
    throw new IndexOutOfBoundsException("offs=" + offs + " len=" + len + " buf.length=" + buf.length);

Type guard

static boolean validSlice(byte[] buf, int offs, int len) {
    return buf != null && offs >= 0 && len >= 0 && offs + len <= buf.length;
}

Try / catch

try {
    compressor.write(buf, offs, len);
} catch (IndexOutOfBoundsException e) {
    throw new IllegalArgumentException("bad write slice: " + e.getMessage(), e);
}

Prevention

When it happens

Trigger: Calling write(buf, offs, len) with offs < 0; also len < 0 or offs + len > buf.length (the adjacent checks). Commonly from a loop computing wrong offsets (e.g. offs += len before advancing) or misread read() results.

Common situations: Manual buffer-chunking loops with off-by-one arithmetic, passing -1 returned from an upstream read() as len, wrong variables swapped in the call.

Related errors


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