{"record":{"id":"50fe0a85d742856c","repo":"zxing/zxing","slug":"sizes-don-t-match","errorCode":null,"errorMessage":"Sizes don't match","messagePattern":"Sizes don't match","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/com/google/zxing/common/BitArray.java","lineNumber":260,"sourceCode":"      if ((value & (1 << numBitsLeft)) != 0) {\n        bits[nextSize / 32] |= 1 << (nextSize & 0x1F);\n      }\n      nextSize++;\n    }\n    size = nextSize;\n  }\n\n  public void appendBitArray(BitArray other) {\n    int otherSize = other.size;\n    ensureCapacity(size + otherSize);\n    for (int i = 0; i < otherSize; i++) {\n      appendBit(other.get(i));\n    }\n  }\n\n  public void xor(BitArray other) {\n    if (size != other.size) {\n      throw new IllegalArgumentException(\"Sizes don't match\");\n    }\n    for (int i = 0; i < bits.length; i++) {\n      // The last int could be incomplete (i.e. not have 32 bits in\n      // it) but there is no problem since 0 XOR 0 == 0.\n      bits[i] ^= other.bits[i];\n    }\n  }\n\n  /**\n   *\n   * @param bitOffset first bit to start writing\n   * @param array array to write into. Bytes are written most-significant byte first. This is the opposite\n   *  of the internal representation, which is exposed by {@link #getBitArray()}\n   * @param offset position in array to start writing\n   * @param numBytes how many bytes to write\n   */\n  public void toBytes(int bitOffset, byte[] array, int offset, int numBytes) {\n    for (int i = 0; i < numBytes; i++) {","sourceCodeStart":242,"sourceCodeEnd":278,"githubUrl":"https://github.com/zxing/zxing/blob/19aa2d8254410e161f04dc3c928e68d5e90233c2/core/src/main/java/com/google/zxing/common/BitArray.java#L242-L278","documentation":"Thrown by BitArray.xor(BitArray other) when this.size != other.size. The XOR operation works by iterating over the raw int[] backing arrays element-by-element, so both arrays must represent exactly the same number of bits to avoid corrupting trailing padding bits or reading out of bounds.","triggerScenarios":"Calling xor() on two BitArrays that were built independently with different lengths — e.g., XORing a data BitArray with a mask pattern BitArray where the mask was generated for a different QR code version.","commonSituations":"QR code mask application where the mask matrix was built with the wrong dimension; unit tests that create mismatched BitArrays; refactoring that changes how one of the arrays is sized.","solutions":["Verify both BitArrays have the same getSize() before calling xor(), and log the mismatch if they differ","Ensure both arrays are constructed from the same dimension parameter — in QR encoding, both the data matrix and mask are created from the same version's module count","If sizes legitimately differ, zero-pad the shorter array to match before XORing"],"exampleFix":"// before\ndata.xor(mask); // mask was built for a different version\n\n// after\nif (data.getSize() != mask.getSize()) {\n    throw new IllegalStateException(\n        \"Mask size \" + mask.getSize()\n        + \" != data size \" + data.getSize());\n}\ndata.xor(mask);","handlingStrategy":"validation","validationCode":"static void xorSafe(BitArray a, BitArray b) {\n    if (a.getSize() != b.getSize()) {\n        throw new IllegalStateException(\n            \"Cannot XOR: size \" + a.getSize()\n            + \" vs \" + b.getSize());\n    }\n    a.xor(b);\n}","typeGuard":"static boolean sameSize(BitArray a, BitArray b) {\n    return a.getSize() == b.getSize();\n}","tryCatchPattern":null,"preventionTips":["Construct both the data array and the mask from the same dimension parameter","Log both sizes in any pre-XOR assertion to speed up debugging","In QR encoding, verify the mask matrix dimension matches the module count for the current version"],"tags":["bitarray","xor","bit-manipulation","qr-code","zxing"],"backgroundTag":null,"analyzedSha":"19aa2d8254410e161f04dc3c928e68d5e90233c2","analyzedAt":"2026-08-14T03:07:53.428Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}