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.

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.

Appendix: 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)