MuntashirAkon/AppManager · error · IndexOutOfBoundsException

len(" + len + ") < 0.

Error message

len(" + len + ") < 0.

What it means

read(byte[], int, int) validates its bounds arguments before touching the stream and throws IndexOutOfBoundsException when len is negative. The library treats a negative length as a programming error in the caller, not an I/O condition, mirroring the contract of java.io.InputStream.

Source

Thrown at app/src/main/java/org/apache/commons/compress/compressors/bzip2/BZip2CompressorInputStream.java:140

            count(r < 0 ? -1 : 1);
            return r;
        }
        throw new IOException("Stream closed");
    }

    /*
     * (non-Javadoc)
     *
     * @see java.io.InputStream#read(byte[], int, int)
     */
    @Override
    public int read(final byte[] dest, final 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 > dest.length) {
            throw new IndexOutOfBoundsException("offs(" + offs + ") + len("
                    + len + ") > dest.length(" + dest.length + ").");
        }
        if (this.bin == null) {
            throw new IOException("Stream closed");
        }
        if (len == 0) {
            return 0;
        }

        final int hi = offs + len;
        int destOffs = offs;
        int b;
        while (destOffs < hi && ((b = read0()) >= 0)) {
            dest[destOffs++] = (byte) b;
            count(1);

View on GitHub (pinned to 0152f468fc)

Solutions

  1. Clamp or validate len >= 0 before calling read (e.g. len = Math.min(len, dest.length - offs)).
  2. Check the counter computation feeding len for underflow (int arithmetic wrapping).
  3. Use a loop pattern like while ((n = in.read(buf, 0, buf.length)) != -1) which never passes negative len.

Example fix

// before
int n = in.read(buf, offs, remaining - 1);
// after
if (remaining < 0) remaining = 0;
int n = in.read(buf, offs, Math.max(0, remaining));
Defensive patterns

Strategy: validation

Validate before calling

if (len < 0) throw new IllegalArgumentException("len must be >= 0");
// or clamp: len = Math.max(0, Math.min(len, dest.length - offs));

Type guard

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

Prevention

When it happens

Trigger: Calling read(dest, offs, -1) or passing any negative length, typically from a computed value that became negative (e.g. remaining = size - offset underflow).

Common situations: Loop bookkeeping bugs where a buffer offset or remaining-bytes counter underflows; passing a user-supplied chunk size without clamping; off-by-one in a custom InputStream wrapper.

Related errors


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