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
- Size the mask to exactly a.capacity() before calling (ByteBuffer.allocate(a.capacity()) and fill mask bytes).
- Pass null as the mask when you want exact (unmasked) equality.
- 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
- Size the mask buffer to exactly a.capacity().
- Pass null mask for exact (unmasked) equality.
- Regenerate masks whenever the signature length changes.
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
- New capacity must fit current contents
- {} is not a constant
- Column {} is not indexed
- Column {} is not of type {}! It is {}
- Given field does not apply to given object type
AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14).
Data as JSON: /api/errors/dfdb692605ffba02.
Report an issue: GitHub.