in src/main/java/org/apache/commons/compress/compressors/bzip2/BZip2CompressorInputStream.java [698:787]
private void recvDecodingTables() throws IOException {
final BitInputStream bin = this.bin;
final Data dataShadow = this.data;
final boolean[] inUse = dataShadow.inUse;
final byte[] pos = dataShadow.recvDecodingTables_pos;
final byte[] selector = dataShadow.selector;
final byte[] selectorMtf = dataShadow.selectorMtf;
int inUse16 = 0;
/* Receive the mapping table */
for (int i = 0; i < 16; i++) {
if (bsGetBit(bin)) {
inUse16 |= 1 << i;
}
}
Arrays.fill(inUse, false);
for (int i = 0; i < 16; i++) {
if ((inUse16 & 1 << i) != 0) {
final int i16 = i << 4;
for (int j = 0; j < 16; j++) {
if (bsGetBit(bin)) {
inUse[i16 + j] = true;
}
}
}
}
makeMaps();
final int alphaSize = this.nInUse + 2;
/* Now the selectors */
final int nGroups = bsR(bin, 3);
final int selectors = bsR(bin, 15);
if (selectors < 0) {
throw new IOException("Corrupted input, nSelectors value negative");
}
checkBounds(alphaSize, MAX_ALPHA_SIZE + 1, "alphaSize");
checkBounds(nGroups, N_GROUPS + 1, "nGroups");
// Don't fail on nSelectors overflowing boundaries but discard the values in overflow
// See https://gnu.wildebeest.org/blog/mjw/2019/08/02/bzip2-and-the-cve-that-wasnt/
// and https://sourceware.org/ml/bzip2-devel/2019-q3/msg00007.html
for (int i = 0; i < selectors; i++) {
int j = 0;
while (bsGetBit(bin)) {
j++;
}
if (i < MAX_SELECTORS) {
selectorMtf[i] = (byte) j;
}
}
final int nSelectors = Math.min(selectors, MAX_SELECTORS);
/* Undo the MTF values for the selectors. */
for (int v = nGroups; --v >= 0;) {
pos[v] = (byte) v;
}
for (int i = 0; i < nSelectors; i++) {
int v = selectorMtf[i] & 0xff;
checkBounds(v, N_GROUPS, "selectorMtf");
final byte tmp = pos[v];
while (v > 0) {
// nearly all times v is zero, 4 in most other cases
pos[v] = pos[v - 1];
v--;
}
pos[0] = tmp;
selector[i] = tmp;
}
final char[][] len = dataShadow.temp_charArray2d;
/* Now the coding tables */
for (int t = 0; t < nGroups; t++) {
int curr = bsR(bin, 5);
final char[] len_t = len[t];
for (int i = 0; i < alphaSize; i++) {
while (bsGetBit(bin)) {
curr += bsGetBit(bin) ? -1 : 1;
}
len_t[i] = (char) curr;
}
}
// finally create the Huffman tables
createHuffmanDecodingTables(alphaSize, nGroups);
}