From c6a4e0fa97da88f586fa91baeae472f7f45dffae Mon Sep 17 00:00:00 2001 From: Sean Owen Date: Sat, 11 Sep 2021 18:03:19 -0500 Subject: [PATCH] Optimization for https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=38541 --- .../zxing/aztec/encoder/BinaryShiftToken.java | 13 +++++++------ .../com/google/zxing/aztec/encoder/State.java | 17 +++++++---------- .../com/google/zxing/common/BitArray.java | 19 +++++++++---------- 3 files changed, 23 insertions(+), 26 deletions(-) diff --git a/core/src/main/java/com/google/zxing/aztec/encoder/BinaryShiftToken.java b/core/src/main/java/com/google/zxing/aztec/encoder/BinaryShiftToken.java index ae83dce7c..969b4dc29 100644 --- a/core/src/main/java/com/google/zxing/aztec/encoder/BinaryShiftToken.java +++ b/core/src/main/java/com/google/zxing/aztec/encoder/BinaryShiftToken.java @@ -33,19 +33,20 @@ final class BinaryShiftToken extends Token { @Override public void appendTo(BitArray bitArray, byte[] text) { - for (int i = 0; i < binaryShiftByteCount; i++) { - if (i == 0 || (i == 31 && binaryShiftByteCount <= 62)) { + int bsbc = binaryShiftByteCount; + for (int i = 0; i < bsbc; i++) { + if (i == 0 || (i == 31 && bsbc <= 62)) { // We need a header before the first character, and before // character 31 when the total byte code is <= 62 bitArray.appendBits(31, 5); // BINARY_SHIFT - if (binaryShiftByteCount > 62) { - bitArray.appendBits(binaryShiftByteCount - 31, 16); + if (bsbc > 62) { + bitArray.appendBits(bsbc - 31, 16); } else if (i == 0) { // 1 <= binaryShiftByteCode <= 62 - bitArray.appendBits(Math.min(binaryShiftByteCount, 31), 5); + bitArray.appendBits(Math.min(bsbc, 31), 5); } else { // 32 <= binaryShiftCount <= 62 and i == 31 - bitArray.appendBits(binaryShiftByteCount - 31, 5); + bitArray.appendBits(bsbc - 31, 5); } } bitArray.appendBits(text[binaryShiftStart + i], 8); diff --git a/core/src/main/java/com/google/zxing/aztec/encoder/State.java b/core/src/main/java/com/google/zxing/aztec/encoder/State.java index acd1ac6d8..7fbd3ca8c 100644 --- a/core/src/main/java/com/google/zxing/aztec/encoder/State.java +++ b/core/src/main/java/com/google/zxing/aztec/encoder/State.java @@ -18,8 +18,8 @@ package com.google.zxing.aztec.encoder; import java.nio.charset.StandardCharsets; -import java.util.Deque; -import java.util.LinkedList; +import java.util.ArrayList; +import java.util.List; import com.google.zxing.common.BitArray; @@ -166,18 +166,15 @@ final class State { } BitArray toBitArray(byte[] text) { - // Reverse the tokens, so that they are in the order that they should - // be output - Deque symbols = new LinkedList<>(); + List symbols = new ArrayList<>(); for (Token token = endBinaryShift(text.length).token; token != null; token = token.getPrevious()) { - symbols.addFirst(token); + symbols.add(token); } BitArray bitArray = new BitArray(); - // Add each token to the result. - for (Token symbol : symbols) { - symbol.appendTo(bitArray, text); + // Add each token to the result in forward order + for (int i = symbols.size() - 1; i >= 0; i--) { + symbols.get(i).appendTo(bitArray, text); } - //assert bitArray.getSize() == this.bitCount; return bitArray; } diff --git a/core/src/main/java/com/google/zxing/common/BitArray.java b/core/src/main/java/com/google/zxing/common/BitArray.java index 19f0c99fd..6685e893c 100644 --- a/core/src/main/java/com/google/zxing/common/BitArray.java +++ b/core/src/main/java/com/google/zxing/common/BitArray.java @@ -233,10 +233,15 @@ public final class BitArray implements Cloneable { if (numBits < 0 || numBits > 32) { throw new IllegalArgumentException("Num bits must be between 0 and 32"); } - ensureCapacity(size + numBits); - for (int numBitsLeft = numBits; numBitsLeft > 0; numBitsLeft--) { - appendBit(((value >> (numBitsLeft - 1)) & 0x01) == 1); + int nextSize = size; + ensureCapacity(nextSize + numBits); + for (int numBitsLeft = numBits - 1; numBitsLeft >= 0; numBitsLeft--) { + if ((value & (1 << numBitsLeft)) != 0) { + bits[nextSize / 32] |= 1 << (nextSize & 0x1F); + } + nextSize++; } + size = nextSize; } public void appendBitArray(BitArray other) { @@ -296,13 +301,7 @@ public final class BitArray implements Cloneable { int len = (size - 1) / 32; int oldBitsLen = len + 1; for (int i = 0; i < oldBitsLen; i++) { - long x = bits[i]; - x = ((x >> 1) & 0x55555555L) | ((x & 0x55555555L) << 1); - x = ((x >> 2) & 0x33333333L) | ((x & 0x33333333L) << 2); - x = ((x >> 4) & 0x0f0f0f0fL) | ((x & 0x0f0f0f0fL) << 4); - x = ((x >> 8) & 0x00ff00ffL) | ((x & 0x00ff00ffL) << 8); - x = ((x >> 16) & 0x0000ffffL) | ((x & 0x0000ffffL) << 16); - newBits[len - i] = (int) x; + newBits[len - i] = Integer.reverse(bits[i]); } // now correct the int's if the bit size isn't a multiple of 32 if (size != oldBitsLen * 32) {