diff --git a/BitBuffer.java b/BitBuffer.java index e9a3dd1..e759aeb 100644 --- a/BitBuffer.java +++ b/BitBuffer.java @@ -66,7 +66,7 @@ final class BitBuffer { // Appends the given number of bits of the given value to this sequence. // If 0 <= len <= 31, then this requires 0 <= val < 2^len. public void appendBits(int val, int len) { - if (len < 0 || len > 32 || len < 32 && (val & ((1 << len) - 1)) != val) + if (len < 0 || len > 32 || len < 32 && (val >>> len) != 0) throw new IllegalArgumentException("Value out of range"); ensureCapacity(bitLength + len); for (int i = len - 1; i >= 0; i--, bitLength++) // Append bit by bit @@ -88,7 +88,7 @@ final class BitBuffer { // Expands the buffer if necessary, so that it can hold at least the given bit length. private void ensureCapacity(int newBitLen) { - while (data.length < newBitLen) + while (data.length * 8 < newBitLen) data = Arrays.copyOf(data, data.length * 2); } diff --git a/QrCode.java b/QrCode.java index 14bc03d..82d20a7 100644 --- a/QrCode.java +++ b/QrCode.java @@ -613,9 +613,9 @@ public final class QrCode { for (int y = 0; y < size - 1; y++) { for (int x = 0; x < size - 1; x++) { boolean color = modules[y][x]; - if ( color == modules[y][x + 1] && - color == modules[y + 1][x] && - color == modules[y + 1][x + 1]) + if ( color == modules[y][x + 1] && + color == modules[y + 1][x] && + color == modules[y + 1][x + 1]) result += PENALTY_N2; } } @@ -694,7 +694,7 @@ public final class QrCode { result -= 64 * 3; // Subtract the three finders with separators result -= 15 * 2 + 1; // Subtract the format information and black module result -= (size - 16) * 2; // Subtract the timing patterns - // The four lines above are equivalent to: int result = (16 * ver + 128) * ver + 64; + // The five lines above are equivalent to: int result = (16 * ver + 128) * ver + 64; if (ver >= 2) { int numAlign = ver / 7 + 2; result -= (numAlign - 1) * (numAlign - 1) * 25; // Subtract alignment patterns not overlapping with timing patterns @@ -711,6 +711,8 @@ public final class QrCode { // QR Code of the given version number and error correction level, with remainder bits discarded. // This stateless pure function could be implemented as a (40*4)-cell lookup table. private static int getNumDataCodewords(int ver, Ecc ecl) { + if (ver < 1 || ver > 40) + throw new IllegalArgumentException("Version number out of range"); return getNumRawDataModules(ver) / 8 - NUM_ERROR_CORRECTION_CODEWORDS[ecl.ordinal()][ver]; } @@ -759,13 +761,13 @@ public final class QrCode { // Constructor. private Ecc(int fb) { formatBits = fb; - } + } } /*---- Private helper class ----*/ - + /** * Computes the Reed-Solomon error correction codewords for a sequence of data codewords * at a given degree. Objects are immutable, and the state only depends on the degree. @@ -843,7 +845,7 @@ public final class QrCode { // Returns the product of the two given field elements modulo GF(2^8/0x11D). The arguments and result // are unsigned 8-bit integers. This could be implemented as a lookup table of 256*256 entries of uint8. private static int multiply(int x, int y) { - if ((x & 0xFF) != x || (y & 0xFF) != y) + if (x >>> 8 != 0 || y >>> 8 != 0) throw new IllegalArgumentException("Byte out of range"); // Russian peasant multiplication int z = 0; @@ -851,7 +853,7 @@ public final class QrCode { z = (z << 1) ^ ((z >>> 7) * 0x11D); z ^= ((y >>> i) & 1) * x; } - if ((z & 0xFF) != z) + if (z >>> 8 != 0) throw new AssertionError(); return z; } diff --git a/qrcodegen.js b/qrcodegen.js index 81b6a6d..103610a 100644 --- a/qrcodegen.js +++ b/qrcodegen.js @@ -566,10 +566,10 @@ var qrcodegen = new function() { // 2*2 blocks of modules having same color for (var y = 0; y < size - 1; y++) { for (var x = 0; x < size - 1; x++) { - var color = modules[y][x]; - if ( color == modules[y][x + 1] && - color == modules[y + 1][x] && - color == modules[y + 1][x + 1]) + var color = modules[y][x]; + if ( color == modules[y][x + 1] && + color == modules[y + 1][x] && + color == modules[y + 1][x + 1]) result += QrCode.PENALTY_N2; } } @@ -658,6 +658,8 @@ var qrcodegen = new function() { // QR Code of the given version number and error correction level, with remainder bits discarded. // This stateless pure function could be implemented as a (40*4)-cell lookup table. QrCode.getNumDataCodewords = function(ver, ecl) { + if (ver < 1 || ver > 40) + throw "Version number out of range"; return Math.floor(QrCode.getNumRawDataModules(ver) / 8) - QrCode.NUM_ERROR_CORRECTION_CODEWORDS[ecl.ordinal][ver]; }; @@ -890,7 +892,7 @@ var qrcodegen = new function() { // This static function returns the product of the two given field elements modulo GF(2^8/0x11D). The arguments and // result are unsigned 8-bit integers. This could be implemented as a lookup table of 256*256 entries of uint8. ReedSolomonGenerator.multiply = function(x, y) { - if ((x & 0xFF) != x || (y & 0xFF) != y) + if (x >>> 8 != 0 || y >>> 8 != 0) throw "Byte out of range"; // Russian peasant multiplication var z = 0; @@ -898,7 +900,7 @@ var qrcodegen = new function() { z = (z << 1) ^ ((z >>> 7) * 0x11D); z ^= ((y >>> i) & 1) * x; } - if ((z & 0xFF) != z) + if (z >>> 8 != 0) throw "Assertion error"; return z; }; @@ -940,7 +942,7 @@ var qrcodegen = new function() { // Appends the given number of bits of the given value to this sequence. // If 0 <= len <= 31, then this requires 0 <= val < 2^len. this.appendBits = function(val, len) { - if (len < 0 || len > 32 || len < 32 && (val & ((1 << len) - 1)) != val) + if (len < 0 || len > 32 || len < 32 && (val >>> len) != 0) throw "Value out of range"; for (var i = len - 1; i >= 0; i--) // Append bit by bit bitData.push((val >>> i) & 1); diff --git a/qrcodegen.py b/qrcodegen.py index 5e858d0..5f5e739 100644 --- a/qrcodegen.py +++ b/qrcodegen.py @@ -548,6 +548,8 @@ class QrCode(object): """Returns the number of 8-bit data (i.e. not error correction) codewords contained in any QR Code of the given version number and error correction level, with remainder bits discarded. This stateless pure function could be implemented as a (40*4)-cell lookup table.""" + if not 1 <= ver <= 40: + raise ValueError("Version number out of range") return QrCode._get_num_raw_data_modules(ver) // 8 - QrCode._NUM_ERROR_CORRECTION_CODEWORDS[ecl.ordinal][ver] @@ -588,14 +590,14 @@ class QrCode(object): # ---- Public helper enumeration ---- - + class Ecc(object): """Represents the error correction level used in a QR Code symbol.""" # Private constructor def __init__(self, i, fb): self.ordinal = i # In the range 0 to 3 (unsigned 2-bit integer) self.formatbits = fb # In the range 0 to 3 (unsigned 2-bit integer) - + # Create the class constants outside the class Ecc.LOW = Ecc(0, 1) Ecc.MEDIUM = Ecc(1, 0) @@ -765,14 +767,14 @@ class _ReedSolomonGenerator(object): def multiply(x, y): """Returns the product of the two given field elements modulo GF(2^8/0x11D). The arguments and result are unsigned 8-bit integers. This could be implemented as a lookup table of 256*256 entries of uint8.""" - if x & 0xFF != x or y & 0xFF != y: + if x >> 8 != 0 or y >> 8 != 0: raise ValueError("Byte out of range") # Russian peasant multiplication z = 0 for i in reversed(range(8)): z = (z << 1) ^ ((z >> 7) * 0x11D) z ^= ((y >> i) & 1) * x - assert z & 0xFF == z + assert z >> 8 == 0 return z