NationalSecurityAgency/ghidra · error · IllegalArgumentException

mask and a must have equal capacities

Error message

mask and a must have equal capacities

What it means

Thrown (unchecked IllegalArgumentException) by ByteBufferUtils.maskedEquals() when a non-null mask buffer's capacity differs from buffer a's capacity. The mask is applied byte-for-byte against both a and b, so it must be the same length as a; a mismatched mask would read out of bounds or mis-compare.

Source

Thrown at Ghidra/Debug/ProposedUtils/src/main/java/ghidra/util/ByteBufferUtils.java:74

	/**
	 * Checks for equality, with a mask applied
	 * 
	 * <p>
	 * This considers the entire contents of both buffers without regard for position or limit. Both
	 * buffers must have equal capacities to be considered equal. The mask, if given, must have
	 * capacity equal to that of the first buffer {@code a} or an exception is thrown.
	 * 
	 * @param mask a buffer containing the mask, or null to match all bytes exactly
	 * @param a the first buffer
	 * @param b the second buffer
	 * @return true if matches, false otherwise
	 * @throws IllegalArgumentException if {@code mask} and {@code a} have unequal capacities
	 */
	public static boolean maskedEquals(ByteBuffer mask, ByteBuffer a, ByteBuffer b) {
		int len = a.capacity();
		if (mask != null && mask.capacity() != len) {
			throw new IllegalArgumentException("mask and a must have equal capacities");
		}
		if (len != a.capacity()) {
			return false;
		}
		if (mask != null) {
			for (int i = 0; i < len; i++) {
				if ((a.get(i) & mask.get(i)) != (b.get(i) & mask.get(i))) {
					return false;
				}
			}
			return true;
		}
		for (int i = 0; i < len; i++) {
			if (a.get(i) != b.get(i)) {
				return false;
			}
		}
		return true;

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Size the mask to exactly a.capacity() before calling (ByteBuffer.allocate(a.capacity()) and fill mask bytes).
  2. Pass null as the mask when you want exact (unmasked) equality.
  3. Validate mask == null || mask.capacity() == a.capacity() before the call and fix the mask source if it mismatches.

Example fix

// before
boolean eq = ByteBufferUtils.maskedEquals(mask, a, b); // throws if mask shorter than a

// after: right-size the mask to a
ByteBuffer sizedMask = mask != null && mask.capacity() != a.capacity()
    ? resizeMaskTo(mask, a.capacity()) : mask;
boolean eq = ByteBufferUtils.maskedEquals(sizedMask, a, b);
Defensive patterns

Strategy: validation

Validate before calling

// Validate mask length against buffer a before comparing
if (mask != null && mask.capacity() != a.capacity()) {
    // resize/rebuild mask to a.capacity(), or pass null for exact match
}

Prevention

When it happens

Trigger: Calling maskedEquals(mask, a, b) where mask.capacity() != a.capacity() — e.g. reusing a mask buffer sized for a different record, building a mask from a wrong-length pattern, or passing a partial mask.

Common situations: Pattern-matching binary signatures where the mask (wildcard bytes) was generated for a different-length signature; copying a mask buffer between unrelated comparisons; a mask built from a hex pattern with the wrong byte count.

Related errors


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