NationalSecurityAgency/ghidra · error · IOException

Invalid number of elements specified: {}

Error message

Invalid number of elements specified: {}

What it means

GBinaryReader.readByteArray(long index, int nElements) rejects a negative element count before delegating to provider.readBytes. It is a precondition guard: the caller passed a count that cannot correspond to a real array length, so the library fails fast rather than producing a NegativeArraySizeException downstream (new byte[nElements]).

Source

Thrown at GPL/DMG/src/dmg/java/mobiledevices/dmg/ghidra/GBinaryReader.java:641

     * @return the LONG
     * @exception IOException if an I/O error occurs
     */
    public long readLong(long index, long minClamp, long maxClamp, Long... exceptions) throws IOException {
        long l = readLong(index);
        return clampLong(l, minClamp, maxClamp, exceptions);
    }

    /**
     * Returns the BYTE array of <code>nElements</code>
     * starting at <code>index</code>.
     * @param index the index where the BYTE begins
     * @param nElements the number of array elements
     * @return the BYTE array
     * @exception IOException if an I/O error occurs
     */
    public byte [] readByteArray(long index, int nElements) throws IOException {
        if (nElements < 0) {
            throw new IOException("Invalid number of elements specified: "+nElements);
        }
        return provider.readBytes(index, nElements);
    }

    /**
     * Returns the BYTE array of <code>nElements</code>
     * starting at <code>index</code>.
     * @param index the index where the BYTE begins
     * @param nElements the number of array elements
     * @return the BYTE array
     * @exception IOException if an I/O error occurs
     */
    public byte [] readByteArray(long index, int nElements, byte minClamp, byte maxClamp, Byte... exceptions) throws IOException {
        byte[] array = readByteArray(index, nElements);
        for (int ii = 0; ii < array.length; ++ii) {
            array[ii] = clampByte(array[ii], minClamp, maxClamp, exceptions);
        }
        return array;

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Check nElements >= 0 at the call site and trace where the negative value originated (log it before calling).
  2. Verify the field supplying nElements is read with the correct size and endianness (use the matching readShort/readInt vs. unsigned variants).
  3. Guard against sentinel/unknown (-1) lengths by mapping them to 0 or skipping the read instead of passing them through.
  4. Validate the parsed structure's length fields against known bounds before indexing.

Example fix

// before
byte[] data = reader.readByteArray(offset, parsedCount);

// after
if (parsedCount < 0) {
    throw new IOException("Invalid parsed length " + parsedCount + " at offset " + offset);
}
byte[] data = reader.readByteArray(offset, parsedCount);
Defensive patterns

Strategy: validation

Validate before calling

if (nElements < 0) {
    throw new IllegalArgumentException("nElements must be >= 0, got " + nElements);
}
byte[] data = reader.readByteArray(index, nElements);

Type guard

private static boolean isNonNegativeCount(int n) { return n >= 0; }

Try / catch

try {
    return reader.readByteArray(index, nElements);
} catch (IOException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("Invalid number of elements")) {
        throw new IllegalArgumentException("readByteArray got negative count", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling readByteArray(index, n) where n is negative. This typically happens when nElements is computed from a parsed length field that was read with the wrong size, wrong endianness, or from a corrupt/truncated structure that yielded -1 or a wrapped negative value.

Common situations: A parsed 'count' field read as a signed value that overflowed; reading a length from an endianness-mismatched header; passing an uninitialized or sentinel (-1) length straight into the array reader; truncated input where a length field is missing.

Related errors


AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14). Data as JSON: /api/errors/2a4c48b484bf9b19. Report an issue: GitHub.