Skip to main content

brotli_decompressor/
decode.rs

1#![allow(non_snake_case)]
2#![allow(unused_parens)]
3#![allow(non_camel_case_types)]
4#![allow(non_snake_case)]
5#![allow(non_upper_case_globals)]
6#![allow(unused_macros)]
7
8// #[macro_use] //<- for debugging, remove xprintln from bit_reader and replace with println
9// extern crate std;
10use core;
11use super::alloc;
12pub use alloc::{AllocatedStackMemory, Allocator, SliceWrapper, SliceWrapperMut, StackAllocator};
13
14use core::mem;
15
16use super::bit_reader;
17use super::huffman;
18use super::state;
19use super::prefix;
20
21use super::transform::{TransformDictionaryWord, kNumTransforms};
22use state::{BlockTypeAndLengthState, BrotliRunningContextMapState, BrotliRunningDecodeUint8State,
23            BrotliRunningHuffmanState, BrotliRunningMetablockHeaderState,
24            BrotliRunningReadBlockLengthState, BrotliRunningState, BrotliRunningTreeGroupState,
25            BrotliRunningUncompressedState, kLiteralContextBits,
26            BrotliDecoderErrorCode, COMPOUND_DICTIONARY_BLOCK_MAP_UNINITIALIZED,
27};
28use context::{kContextLookup};
29use ::dictionary::{kBrotliDictionary, kBrotliDictionaryOffsetsByLength,
30                   kBrotliDictionarySizeBitsByLength, kBrotliMaxDictionaryWordLength,
31                   kBrotliMinDictionaryWordLength};
32use ::shared_dictionary::{SHARED_BROTLI_MIN_DICTIONARY_WORD_LENGTH,
33                          SHARED_BROTLI_MAX_DICTIONARY_WORD_LENGTH,
34                          SHARED_BROTLI_MAX_TRANSFORM_AFFIX_LENGTH,
35                          DictionaryLookupError};
36pub use huffman::{HuffmanCode, HuffmanTreeGroup};
37#[repr(C)]
38#[derive(Debug)]
39pub enum BrotliResult {
40  ResultSuccess = 1,
41  NeedsMoreInput = 2,
42  NeedsMoreOutput = 3,
43  ResultFailure = 0,
44}
45const kBrotliWindowGap: u32 = 16;
46const kBrotliLargeMinWbits: u32 = 10;
47const kBrotliLargeMaxWbits: u32 = 30;
48const kBrotliMaxPostfix: usize = 3;
49const kBrotliMaxAllowedDistance: u32 = 0x7FFFFFFC;
50const kDefaultCodeLength: u32 = 8;
51const kCodeLengthRepeatCode: u32 = 16;
52pub const kNumLiteralCodes: u16 = 256;
53pub const kNumInsertAndCopyCodes: u16 = 704;
54pub const kNumBlockLengthCodes: u32 = 26;
55const kDistanceContextBits: i32 = 2;
56const HUFFMAN_TABLE_BITS: u32 = 8;
57const HUFFMAN_TABLE_MASK: u32 = 0xff;
58const CODE_LENGTH_CODES: usize = 18;
59const kCodeLengthCodeOrder: [u8; CODE_LENGTH_CODES] = [1, 2, 3, 4, 0, 5, 17, 6, 16, 7, 8, 9, 10,
60                                                       11, 12, 13, 14, 15];
61
62// Static prefix code for the complex code length code lengths.
63const kCodeLengthPrefixLength: [u8; 16] = [2, 2, 2, 3, 2, 2, 2, 4, 2, 2, 2, 3, 2, 2, 2, 4];
64
65const kCodeLengthPrefixValue: [u8; 16] = [0, 4, 3, 2, 0, 4, 3, 1, 0, 4, 3, 2, 0, 4, 3, 5];
66
67
68macro_rules! BROTLI_LOG_UINT (
69    ($num : expr) => {
70       xprintln!("{:?} = {:?}", stringify!($num),  $num)
71    };
72);
73
74macro_rules! BROTLI_LOG (
75    ($str : expr, $num : expr) => {xprintln!("{:?} {:?}", $str, $num);};
76    ($str : expr, $num0 : expr, $num1 : expr) => {xprintln!("{:?} {:?} {:?}", $str, $num0, $num1);};
77    ($str : expr, $num0 : expr, $num1 : expr, $num2 : expr) => {
78        xprintln!("{:?} {:?} {:?} {:?}", $str, $num0, $num1, $num2);
79    };
80    ($str : expr, $num0 : expr, $num1 : expr, $num2 : expr, $num3 : expr) => {
81        xprintln!("{:?} {:?} {:?} {:?} {:?}", $str, $num0, $num1, $num2, $num3);
82    };
83);
84fn is_fatal(e: BrotliDecoderErrorCode) -> bool {
85  (e as i64) < 0
86}
87fn assign_error_code(output: &mut BrotliDecoderErrorCode, input: BrotliDecoderErrorCode) -> BrotliDecoderErrorCode {
88  *output = input;
89  input
90}
91
92#[allow(non_snake_case)]
93macro_rules! SaveErrorCode {
94  ($state: expr, $e:expr) => {
95    match assign_error_code(&mut $state.error_code, $e) {
96      BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS =>
97        BrotliResult::ResultSuccess,
98      BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT =>
99        BrotliResult::NeedsMoreInput,
100      BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_OUTPUT =>
101        BrotliResult::NeedsMoreOutput,
102      _ =>
103        BrotliResult::ResultFailure,
104    }
105  }
106}
107macro_rules! SaveResult {
108  ($state: expr, $e:expr) => {
109    match ($state.error_code = match $e  {
110      BrotliResult::ResultSuccess => BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS,
111      BrotliResult::NeedsMoreInput => BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT,
112      BrotliResult::NeedsMoreOutput => BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_OUTPUT,
113      BrotliResult::ResultFailure => BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_UNREACHABLE,
114    }) {
115      BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS =>
116        BrotliResult::ResultSuccess,
117      BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT =>
118        BrotliResult::NeedsMoreInput,
119      BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_OUTPUT =>
120        BrotliResult::NeedsMoreOutput,
121      _ =>
122        BrotliResult::ResultFailure,
123    }
124  }
125}
126macro_rules! BROTLI_LOG_ARRAY_INDEX (
127    ($array : expr, $index : expr) => {
128       xprintln!("{:?}[{:?}] = {:?}", stringify!($array), $index,  $array[$index as usize])
129    };
130);
131
132
133const NUM_DISTANCE_SHORT_CODES: u32 = 16;
134pub const BROTLI_MAX_DISTANCE_BITS:u32 = 24;
135
136pub const BROTLI_LARGE_MAX_DISTANCE_BITS: u32 = 62;
137
138pub fn BROTLI_DISTANCE_ALPHABET_SIZE(NPOSTFIX: u32, NDIRECT:u32, MAXNBITS: u32) -> u32 {
139    NUM_DISTANCE_SHORT_CODES + (NDIRECT) +
140        ((MAXNBITS) << ((NPOSTFIX) + 1))
141}
142
143// pub struct BrotliState {
144// total_written : usize,
145// }
146//
147pub use state::BrotliState;
148// impl BrotliState {
149// pub fn new() -> BrotliState {
150// return BrotliState {total_written: 0 };
151// }
152// }
153
154/* Decodes WBITS by reading 1 - 7 bits, or 0x11 for "Large Window Brotli".
155   Precondition: bit-reader accumulator has at least 8 bits. */
156fn DecodeWindowBits(s_large_window: &mut bool,
157                    s_window_bits:&mut u32,
158                    br: &mut bit_reader::BrotliBitReader) -> BrotliDecoderErrorCode {
159  let mut n: u32 = 0;
160  let large_window = *s_large_window;
161  *s_large_window = false;
162  bit_reader::BrotliTakeBits(br, 1, &mut n);
163  if (n == 0) {
164    *s_window_bits = 16;
165    return BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS;
166  }
167  bit_reader::BrotliTakeBits(br, 3, &mut n);
168  if (n != 0) {
169    *s_window_bits = 17 + n;
170    return BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS;
171  }
172  bit_reader::BrotliTakeBits(br, 3, &mut n);
173  if (n == 1) {
174    if (large_window) {
175      bit_reader::BrotliTakeBits(br, 1, &mut n);
176      if (n == 1) {
177        return BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS;
178      }
179      *s_large_window = true;
180      return BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS;
181    } else {
182      return BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS;
183    }
184  }
185  if (n != 0) {
186    *s_window_bits = 8 + n;
187    return BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS;
188  }
189  *s_window_bits = 17;
190  return BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS;
191}
192
193
194#[cold]
195fn mark_unlikely() {}
196
197fn DecodeVarLenUint8(substate_decode_uint8: &mut state::BrotliRunningDecodeUint8State,
198                     mut br: &mut bit_reader::BrotliBitReader,
199                     value: &mut u32,
200                     input: &[u8])
201                     -> BrotliDecoderErrorCode {
202  let mut bits: u32 = 0;
203  loop {
204    match *substate_decode_uint8 {
205      BrotliRunningDecodeUint8State::BROTLI_STATE_DECODE_UINT8_NONE => {
206        if !bit_reader::BrotliSafeReadBits(&mut br, 1, &mut bits, input) {
207          mark_unlikely();
208          return BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT;
209        }
210        if (bits == 0) {
211          *value = 0;
212          return BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS;
213        }
214        *substate_decode_uint8 = BrotliRunningDecodeUint8State::BROTLI_STATE_DECODE_UINT8_SHORT;
215        // No break, transit to the next state.
216      }
217      BrotliRunningDecodeUint8State::BROTLI_STATE_DECODE_UINT8_SHORT => {
218        if !bit_reader::BrotliSafeReadBits(&mut br, 3, &mut bits, input) {
219          mark_unlikely();
220          *substate_decode_uint8 = BrotliRunningDecodeUint8State::BROTLI_STATE_DECODE_UINT8_SHORT;
221          return BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT;
222        }
223        if (bits == 0) {
224          *value = 1;
225          *substate_decode_uint8 = BrotliRunningDecodeUint8State::BROTLI_STATE_DECODE_UINT8_NONE;
226          return BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS;
227        }
228        // Use output value as a temporary storage. It MUST be persisted.
229        *value = bits;
230        // No break, transit to the next state.
231        *substate_decode_uint8 = BrotliRunningDecodeUint8State::BROTLI_STATE_DECODE_UINT8_LONG;
232      }
233      BrotliRunningDecodeUint8State::BROTLI_STATE_DECODE_UINT8_LONG => {
234        if !bit_reader::BrotliSafeReadBits(&mut br, *value, &mut bits, input) {
235          mark_unlikely();
236          *substate_decode_uint8 = BrotliRunningDecodeUint8State::BROTLI_STATE_DECODE_UINT8_LONG;
237          return BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT;
238        }
239        *value = (1u32 << *value) + bits;
240        *substate_decode_uint8 = BrotliRunningDecodeUint8State::BROTLI_STATE_DECODE_UINT8_NONE;
241        return BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS;
242      }
243    }
244  }
245}
246
247fn DecodeMetaBlockLength<AllocU8: alloc::Allocator<u8>,
248                         AllocU32: alloc::Allocator<u32>,
249                         AllocHC: alloc::Allocator<HuffmanCode>>
250  (s: &mut BrotliState<AllocU8, AllocU32, AllocHC>,
251   input: &[u8])
252   -> BrotliDecoderErrorCode {
253  let mut bits: u32 = 0;
254  loop {
255    match s.substate_metablock_header {
256      BrotliRunningMetablockHeaderState::BROTLI_STATE_METABLOCK_HEADER_NONE => {
257        if !bit_reader::BrotliSafeReadBits(&mut s.br, 1, &mut bits, input) {
258          return BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT;
259        }
260        s.is_last_metablock = bits as u8;
261        s.meta_block_remaining_len = 0;
262        s.is_uncompressed = 0;
263        s.is_metadata = 0;
264        if (s.is_last_metablock == 0) {
265          s.substate_metablock_header =
266            BrotliRunningMetablockHeaderState::BROTLI_STATE_METABLOCK_HEADER_NIBBLES;
267          continue;
268        }
269        s.substate_metablock_header =
270          BrotliRunningMetablockHeaderState::BROTLI_STATE_METABLOCK_HEADER_EMPTY;
271        // No break, transit to the next state.
272      }
273      BrotliRunningMetablockHeaderState::BROTLI_STATE_METABLOCK_HEADER_EMPTY => {
274        if !bit_reader::BrotliSafeReadBits(&mut s.br, 1, &mut bits, input) {
275          return BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT;
276        }
277        if bits != 0 {
278          s.substate_metablock_header =
279            BrotliRunningMetablockHeaderState::BROTLI_STATE_METABLOCK_HEADER_NONE;
280          return BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS;
281        }
282        s.substate_metablock_header =
283          BrotliRunningMetablockHeaderState::BROTLI_STATE_METABLOCK_HEADER_NIBBLES;
284        // No break, transit to the next state.
285      }
286      BrotliRunningMetablockHeaderState::BROTLI_STATE_METABLOCK_HEADER_NIBBLES => {
287        if !bit_reader::BrotliSafeReadBits(&mut s.br, 2, &mut bits, input) {
288          return BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT;
289        }
290        s.size_nibbles = (bits + 4) as u8;
291        s.loop_counter = 0;
292        if (bits == 3) {
293          s.is_metadata = 1;
294          s.substate_metablock_header =
295            BrotliRunningMetablockHeaderState::BROTLI_STATE_METABLOCK_HEADER_RESERVED;
296          continue;
297        }
298        s.substate_metablock_header =
299          BrotliRunningMetablockHeaderState::BROTLI_STATE_METABLOCK_HEADER_SIZE;
300        // No break, transit to the next state.
301
302      }
303      BrotliRunningMetablockHeaderState::BROTLI_STATE_METABLOCK_HEADER_SIZE => {
304        let mut i = s.loop_counter;
305        while i < s.size_nibbles as i32 {
306          if !bit_reader::BrotliSafeReadBits(&mut s.br, 4, &mut bits, input) {
307            s.loop_counter = i;
308            return BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT;
309          }
310          if (i + 1 == s.size_nibbles as i32 && s.size_nibbles > 4 && bits == 0) {
311            return BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_NIBBLE;
312          }
313          s.meta_block_remaining_len |= (bits << (i * 4)) as i32;
314          i += 1;
315        }
316        s.substate_metablock_header =
317          BrotliRunningMetablockHeaderState::BROTLI_STATE_METABLOCK_HEADER_UNCOMPRESSED;
318        // No break, transit to the next state.
319      }
320      BrotliRunningMetablockHeaderState::BROTLI_STATE_METABLOCK_HEADER_UNCOMPRESSED => {
321        if (s.is_last_metablock == 0 && s.is_metadata == 0) {
322          if !bit_reader::BrotliSafeReadBits(&mut s.br, 1, &mut bits, input) {
323            return BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT;
324          }
325          s.is_uncompressed = bits as u8;
326        }
327        s.meta_block_remaining_len += 1;
328        s.substate_metablock_header =
329          BrotliRunningMetablockHeaderState::BROTLI_STATE_METABLOCK_HEADER_NONE;
330        return BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS;
331      }
332      BrotliRunningMetablockHeaderState::BROTLI_STATE_METABLOCK_HEADER_RESERVED => {
333        if !bit_reader::BrotliSafeReadBits(&mut s.br, 1, &mut bits, input) {
334          return BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT;
335        }
336        if (bits != 0) {
337          return BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_FORMAT_RESERVED;
338        }
339        s.substate_metablock_header =
340          BrotliRunningMetablockHeaderState::BROTLI_STATE_METABLOCK_HEADER_BYTES;
341        // No break, transit to the next state.
342      }
343      BrotliRunningMetablockHeaderState::BROTLI_STATE_METABLOCK_HEADER_BYTES => {
344        if !bit_reader::BrotliSafeReadBits(&mut s.br, 2, &mut bits, input) {
345          return BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT;
346        }
347        if (bits == 0) {
348          s.substate_metablock_header =
349            BrotliRunningMetablockHeaderState::BROTLI_STATE_METABLOCK_HEADER_NONE;
350          return BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS;
351        }
352        s.size_nibbles = bits as u8;
353        s.substate_metablock_header =
354          BrotliRunningMetablockHeaderState::BROTLI_STATE_METABLOCK_HEADER_METADATA;
355        // No break, transit to the next state.
356      }
357      BrotliRunningMetablockHeaderState::BROTLI_STATE_METABLOCK_HEADER_METADATA => {
358        let mut i = s.loop_counter;
359        while i < s.size_nibbles as i32 {
360          if !bit_reader::BrotliSafeReadBits(&mut s.br, 8, &mut bits, input) {
361            s.loop_counter = i;
362            return BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT;
363          }
364          if (i + 1 == s.size_nibbles as i32 && s.size_nibbles > 1 && bits == 0) {
365            return BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_META_NIBBLE;
366          }
367          s.meta_block_remaining_len |= (bits << (i * 8)) as i32;
368          i += 1;
369        }
370        s.substate_metablock_header =
371          BrotliRunningMetablockHeaderState::BROTLI_STATE_METABLOCK_HEADER_UNCOMPRESSED;
372        continue;
373      }
374    }
375  }
376}
377// Decodes the Huffman code.
378// This method doesn't read data from the bit reader, BUT drops the amount of
379// bits that correspond to the decoded symbol.
380// bits MUST contain at least 15 (BROTLI_HUFFMAN_MAX_CODE_LENGTH) valid bits.
381#[inline(always)]
382fn DecodeSymbol(bits: u32, table: &[HuffmanCode], br: &mut bit_reader::BrotliBitReader) -> u32 {
383  let mut table_index = bits & HUFFMAN_TABLE_MASK;
384  let mut table_element = fast!((table)[table_index as usize]);
385  if table_element.bits > HUFFMAN_TABLE_BITS as u8 {
386    let nbits = table_element.bits - HUFFMAN_TABLE_BITS as u8;
387    bit_reader::BrotliDropBits(br, HUFFMAN_TABLE_BITS);
388    table_index += table_element.value as u32;
389    table_element = fast!((table)[(table_index
390                           + ((bits >> HUFFMAN_TABLE_BITS)
391                              & bit_reader::BitMask(nbits as u32))) as usize]);
392  }
393  bit_reader::BrotliDropBits(br, table_element.bits as u32);
394  table_element.value as u32
395}
396
397// Reads and decodes the next Huffman code from bit-stream.
398// This method peeks 16 bits of input and drops 0 - 15 of them.
399#[inline(always)]
400fn ReadSymbol(table: &[HuffmanCode], br: &mut bit_reader::BrotliBitReader, input: &[u8]) -> u32 {
401  DecodeSymbol(bit_reader::BrotliGet16BitsUnmasked(br, input), table, br)
402}
403
404// Same as DecodeSymbol, but it is known that there is less than 15 bits of
405// input are currently available.
406fn SafeDecodeSymbol(table: &[HuffmanCode],
407                    mut br: &mut bit_reader::BrotliBitReader,
408                    result: &mut u32)
409                    -> bool {
410  let mut available_bits = bit_reader::BrotliGetAvailableBits(br);
411  if (available_bits == 0) {
412    if (fast!((table)[0]).bits == 0) {
413      *result = fast!((table)[0]).value as u32;
414      return true;
415    }
416    return false; /* No valid bits at all. */
417  }
418  let mut val = bit_reader::BrotliGetBitsUnmasked(br) as u32;
419  let table_index = (val & HUFFMAN_TABLE_MASK) as usize;
420  let table_element = fast!((table)[table_index]);
421  if (table_element.bits <= HUFFMAN_TABLE_BITS as u8) {
422    if (table_element.bits as u32 <= available_bits) {
423      bit_reader::BrotliDropBits(&mut br, table_element.bits as u32);
424      *result = table_element.value as u32;
425      return true;
426    } else {
427      return false; /* Not enough bits for the first level. */
428    }
429  }
430  if (available_bits <= HUFFMAN_TABLE_BITS) {
431    return false; /* Not enough bits to move to the second level. */
432  }
433
434  // Speculatively drop HUFFMAN_TABLE_BITS.
435  val = (val & bit_reader::BitMask(table_element.bits as u32)) >> HUFFMAN_TABLE_BITS;
436  available_bits -= HUFFMAN_TABLE_BITS;
437  let table_sub_element = fast!((table)[table_index + table_element.value as usize + val as usize]);
438  if (available_bits < table_sub_element.bits as u32) {
439    return false; /* Not enough bits for the second level. */
440  }
441
442  bit_reader::BrotliDropBits(&mut br, HUFFMAN_TABLE_BITS + table_sub_element.bits as u32);
443  *result = table_sub_element.value as u32;
444  true
445}
446
447fn SafeReadSymbol(table: &[HuffmanCode],
448                  br: &mut bit_reader::BrotliBitReader,
449                  result: &mut u32,
450                  input: &[u8])
451                  -> bool {
452  let mut val: u32 = 0;
453  if (bit_reader::BrotliSafeGetBits(br, 15, &mut val, input)) {
454    *result = DecodeSymbol(val, table, br);
455    return true;
456  } else {
457    mark_unlikely();
458  }
459  SafeDecodeSymbol(table, br, result)
460}
461
462// Makes a look-up in first level Huffman table. Peeks 8 bits.
463#[inline(always)]
464fn PreloadSymbol(safe: bool,
465                 table: &[HuffmanCode],
466                 br: &mut bit_reader::BrotliBitReader,
467                 bits: &mut u32,
468                 value: &mut u32,
469                 input: &[u8]) {
470  if (safe) {
471    return;
472  }
473  let table_element =
474    fast!((table)[bit_reader::BrotliGetBits(br, HUFFMAN_TABLE_BITS, input) as usize]);
475  *bits = table_element.bits as u32;
476  *value = table_element.value as u32;
477}
478
479// Decodes the next Huffman code using data prepared by PreloadSymbol.
480// Reads 0 - 15 bits. Also peeks 8 following bits.
481#[inline(always)]
482fn ReadPreloadedSymbol(table: &[HuffmanCode],
483                       br: &mut bit_reader::BrotliBitReader,
484                       bits: &mut u32,
485                       value: &mut u32,
486                       input: &[u8])
487                       -> u32 {
488  let result = if *bits > HUFFMAN_TABLE_BITS {
489    mark_unlikely();
490    let val = bit_reader::BrotliGet16BitsUnmasked(br, input);
491    let mut ext_index = (val & HUFFMAN_TABLE_MASK) + *value;
492    let mask = bit_reader::BitMask((*bits - HUFFMAN_TABLE_BITS));
493    bit_reader::BrotliDropBits(br, HUFFMAN_TABLE_BITS);
494    ext_index += (val >> HUFFMAN_TABLE_BITS) & mask;
495    let ext = fast!((table)[ext_index as usize]);
496    bit_reader::BrotliDropBits(br, ext.bits as u32);
497    ext.value as u32
498  } else {
499    bit_reader::BrotliDropBits(br, *bits);
500    *value
501  };
502  PreloadSymbol(false, table, br, bits, value, input);
503  result
504}
505
506fn Log2Floor(mut x: u32) -> u32 {
507  let mut result: u32 = 0;
508  while x != 0 {
509    x >>= 1;
510    result += 1;
511  }
512  result
513}
514
515
516// Reads (s->symbol + 1) symbols.
517// Totally 1..4 symbols are read, 1..11 bits each.
518// The list of symbols MUST NOT contain duplicates.
519//
520fn ReadSimpleHuffmanSymbols<AllocU8: alloc::Allocator<u8>,
521                            AllocU32: alloc::Allocator<u32>,
522                            AllocHC: alloc::Allocator<HuffmanCode>>
523  (alphabet_size: u32, max_symbol: u32,
524   s: &mut BrotliState<AllocU8, AllocU32, AllocHC>,
525   input: &[u8])
526   -> BrotliDecoderErrorCode {
527
528  // max_bits == 1..11; symbol == 0..3; 1..44 bits will be read.
529  let max_bits = Log2Floor(alphabet_size - 1);
530  let mut i = s.sub_loop_counter;
531  let num_symbols = s.symbol;
532  for symbols_lists_item in fast_mut!((s.symbols_lists_array)[s.sub_loop_counter as usize;
533                                                  num_symbols as usize + 1])
534    .iter_mut() {
535    let mut v: u32 = 0;
536    if !bit_reader::BrotliSafeReadBits(&mut s.br, max_bits, &mut v, input) {
537      mark_unlikely();
538      s.sub_loop_counter = i;
539      s.substate_huffman = BrotliRunningHuffmanState::BROTLI_STATE_HUFFMAN_SIMPLE_READ;
540      return BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT;
541    }
542    if (v >= max_symbol) {
543      return BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_ALPHABET;
544    }
545    *symbols_lists_item = v as u16;
546    BROTLI_LOG_UINT!(v);
547    i += 1;
548  }
549  i = 0;
550  for symbols_list_item in fast!((s.symbols_lists_array)[0; num_symbols as usize]).iter() {
551    for other_item in fast!((s.symbols_lists_array)[i as usize + 1 ; num_symbols as usize+ 1])
552      .iter() {
553      if (*symbols_list_item == *other_item) {
554        return BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_SAME;
555      }
556    }
557    i += 1;
558  }
559  BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS
560}
561
562// Process single decoded symbol code length:
563// A) reset the repeat variable
564// B) remember code length (if it is not 0)
565// C) extend corredponding index-chain
566// D) reduce the huffman space
567// E) update the histogram
568//
569fn ProcessSingleCodeLength(code_len: u32,
570                           symbol: &mut u32,
571                           repeat: &mut u32,
572                           space: &mut u32,
573                           prev_code_len: &mut u32,
574                           symbol_lists: &mut [u16],
575                           symbol_list_index_offset: usize,
576                           code_length_histo: &mut [u16],
577                           next_symbol: &mut [i32]) {
578  *repeat = 0;
579  if (code_len != 0) {
580    // code_len == 1..15
581    // next_symbol may be negative, hence we have to supply offset to function
582    fast_mut!((symbol_lists)[(symbol_list_index_offset as i32 +
583                             fast_inner!((next_symbol)[code_len as usize])) as usize]) =
584      (*symbol) as u16;
585    fast_mut!((next_symbol)[code_len as usize]) = (*symbol) as i32;
586    *prev_code_len = code_len;
587    *space = space.wrapping_sub(32768 >> code_len);
588    fast_mut!((code_length_histo)[code_len as usize]) += 1;
589    BROTLI_LOG!("[ReadHuffmanCode] code_length[{:}]={:} histo[]={:}\n",
590                *symbol, code_len, code_length_histo[code_len as usize]);
591  }
592  (*symbol) += 1;
593}
594
595// Process repeated symbol code length.
596// A) Check if it is the extension of previous repeat sequence; if the decoded
597// value is not kCodeLengthRepeatCode, then it is a new symbol-skip
598// B) Update repeat variable
599// C) Check if operation is feasible (fits alphapet)
600// D) For each symbol do the same operations as in ProcessSingleCodeLength
601//
602// PRECONDITION: code_len == kCodeLengthRepeatCode or kCodeLengthRepeatCode + 1
603//
604fn ProcessRepeatedCodeLength(code_len: u32,
605                             mut repeat_delta: u32,
606                             alphabet_size: u32,
607                             symbol: &mut u32,
608                             repeat: &mut u32,
609                             space: &mut u32,
610                             prev_code_len: &mut u32,
611                             repeat_code_len: &mut u32,
612                             symbol_lists: &mut [u16],
613                             symbol_lists_index: usize,
614                             code_length_histo: &mut [u16],
615                             next_symbol: &mut [i32]) {
616  let old_repeat: u32;
617  let extra_bits: u32;
618  let new_len: u32;
619  if (code_len == kCodeLengthRepeatCode) {
620    extra_bits = 2;
621    new_len = *prev_code_len
622  } else {
623    extra_bits = 3;
624    new_len = 0
625  }
626  if (*repeat_code_len != new_len) {
627    *repeat = 0;
628    *repeat_code_len = new_len;
629  }
630  old_repeat = *repeat;
631  if (*repeat > 0) {
632    *repeat -= 2;
633    *repeat <<= extra_bits;
634  }
635  *repeat += repeat_delta + 3;
636  repeat_delta = *repeat - old_repeat;
637  if (*symbol + repeat_delta > alphabet_size) {
638    *symbol = alphabet_size;
639    *space = 0xFFFFF;
640    return;
641  }
642  BROTLI_LOG!("[ReadHuffmanCode] code_length[{:}..{:}] = {:}\n",
643              *symbol, *symbol + repeat_delta - 1, *repeat_code_len);
644  if (*repeat_code_len != 0) {
645    let last: u32 = *symbol + repeat_delta;
646    let mut next: i32 = fast!((next_symbol)[*repeat_code_len as usize]);
647    loop {
648      fast_mut!((symbol_lists)[(symbol_lists_index as i32 + next) as usize]) = (*symbol) as u16;
649      next = (*symbol) as i32;
650      (*symbol) += 1;
651      if *symbol == last {
652        break;
653      }
654    }
655    fast_mut!((next_symbol)[*repeat_code_len as usize]) = next;
656    *space = space.wrapping_sub(repeat_delta << (15 - *repeat_code_len));
657    fast_mut!((code_length_histo)[*repeat_code_len as usize]) =
658      (fast!((code_length_histo)[*repeat_code_len as usize]) as u32 + repeat_delta) as u16;
659  } else {
660    *symbol += repeat_delta;
661  }
662}
663
664// Reads and decodes symbol codelengths.
665fn ReadSymbolCodeLengths<AllocU8: alloc::Allocator<u8>,
666                         AllocU32: alloc::Allocator<u32>,
667                         AllocHC: alloc::Allocator<HuffmanCode>>
668  (alphabet_size: u32,
669   s: &mut BrotliState<AllocU8, AllocU32, AllocHC>,
670   input: &[u8])
671   -> BrotliDecoderErrorCode {
672
673  let mut symbol = s.symbol;
674  let mut repeat = s.repeat;
675  let mut space = s.space;
676  let mut prev_code_len: u32 = s.prev_code_len;
677  let mut repeat_code_len: u32 = s.repeat_code_len;
678  if (!bit_reader::BrotliWarmupBitReader(&mut s.br, input)) {
679    return BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT;
680  }
681  while (symbol < alphabet_size && space > 0) {
682    let mut p_index = 0;
683    let code_len: u32;
684    if (!bit_reader::BrotliCheckInputAmount(&s.br, bit_reader::BROTLI_SHORT_FILL_BIT_WINDOW_READ)) {
685      s.symbol = symbol;
686      s.repeat = repeat;
687      s.prev_code_len = prev_code_len;
688      s.repeat_code_len = repeat_code_len;
689      s.space = space;
690      return BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT;
691    }
692    bit_reader::BrotliFillBitWindow16(&mut s.br, input);
693    p_index +=
694      bit_reader::BrotliGetBitsUnmasked(&s.br) &
695      bit_reader::BitMask(huffman::BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH as u32) as u64;
696    let p = fast!((s.table)[p_index as usize]);
697    bit_reader::BrotliDropBits(&mut s.br, p.bits as u32); /* Use 1..5 bits */
698    code_len = p.value as u32; /* code_len == 0..17 */
699    if (code_len < kCodeLengthRepeatCode) {
700      ProcessSingleCodeLength(code_len,
701                              &mut symbol,
702                              &mut repeat,
703                              &mut space,
704                              &mut prev_code_len,
705                              &mut s.symbols_lists_array,
706                              s.symbol_lists_index as usize,
707                              &mut s.code_length_histo[..],
708                              &mut s.next_symbol[..]);
709    } else {
710      // code_len == 16..17, extra_bits == 2..3
711      let extra_bits: u32 = if code_len == kCodeLengthRepeatCode {
712        2
713      } else {
714        3
715      };
716      let repeat_delta: u32 = bit_reader::BrotliGetBitsUnmasked(&s.br) as u32 &
717                              bit_reader::BitMask(extra_bits);
718      bit_reader::BrotliDropBits(&mut s.br, extra_bits);
719      ProcessRepeatedCodeLength(code_len,
720                                repeat_delta,
721                                alphabet_size,
722                                &mut symbol,
723                                &mut repeat,
724                                &mut space,
725                                &mut prev_code_len,
726                                &mut repeat_code_len,
727                                &mut s.symbols_lists_array,
728                                s.symbol_lists_index as usize,
729                                &mut s.code_length_histo[..],
730                                &mut s.next_symbol[..]);
731    }
732  }
733  s.space = space;
734  BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS
735}
736
737fn SafeReadSymbolCodeLengths<AllocU8: alloc::Allocator<u8>,
738                             AllocU32: alloc::Allocator<u32>,
739                             AllocHC: alloc::Allocator<HuffmanCode>>
740  (alphabet_size: u32,
741   s: &mut BrotliState<AllocU8, AllocU32, AllocHC>,
742   input: &[u8])
743   -> BrotliDecoderErrorCode {
744  while (s.symbol < alphabet_size && s.space > 0) {
745    let mut p_index = 0;
746    let code_len: u32;
747    let mut bits: u32 = 0;
748    let available_bits: u32 = bit_reader::BrotliGetAvailableBits(&s.br);
749    if (available_bits != 0) {
750      bits = bit_reader::BrotliGetBitsUnmasked(&s.br) as u32;
751    }
752    p_index += bits &
753               bit_reader::BitMask(huffman::BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH as u32);
754    let p = fast!((s.table)[p_index as usize]);
755    if (p.bits as u32 > available_bits) {
756      // pullMoreInput;
757      if (!bit_reader::BrotliPullByte(&mut s.br, input)) {
758        return BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT;
759      }
760      continue;
761    }
762    code_len = p.value as u32; /* code_len == 0..17 */
763    if (code_len < kCodeLengthRepeatCode) {
764      bit_reader::BrotliDropBits(&mut s.br, p.bits as u32);
765      ProcessSingleCodeLength(code_len,
766                              &mut s.symbol,
767                              &mut s.repeat,
768                              &mut s.space,
769                              &mut s.prev_code_len,
770                              &mut s.symbols_lists_array,
771                              s.symbol_lists_index as usize,
772                              &mut s.code_length_histo[..],
773                              &mut s.next_symbol[..]);
774    } else {
775      // code_len == 16..17, extra_bits == 2..3
776      let extra_bits: u32 = code_len - 14;
777      let repeat_delta: u32 = (bits >> p.bits) & bit_reader::BitMask(extra_bits);
778      if (available_bits < p.bits as u32 + extra_bits) {
779        // pullMoreInput;
780        if (!bit_reader::BrotliPullByte(&mut s.br, input)) {
781          return BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT;
782        }
783        continue;
784      }
785      bit_reader::BrotliDropBits(&mut s.br, p.bits as u32 + extra_bits);
786      ProcessRepeatedCodeLength(code_len,
787                                repeat_delta,
788                                alphabet_size,
789                                &mut s.symbol,
790                                &mut s.repeat,
791                                &mut s.space,
792                                &mut s.prev_code_len,
793                                &mut s.repeat_code_len,
794                                &mut s.symbols_lists_array,
795                                s.symbol_lists_index as usize,
796                                &mut s.code_length_histo[..],
797                                &mut s.next_symbol[..]);
798    }
799  }
800  BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS
801}
802
803// Reads and decodes 15..18 codes using static prefix code.
804// Each code is 2..4 bits long. In total 30..72 bits are used.
805fn ReadCodeLengthCodeLengths<AllocU8: alloc::Allocator<u8>,
806                             AllocU32: alloc::Allocator<u32>,
807                             AllocHC: alloc::Allocator<HuffmanCode>>
808  (s: &mut BrotliState<AllocU8, AllocU32, AllocHC>,
809   input: &[u8])
810   -> BrotliDecoderErrorCode {
811
812  let mut num_codes: u32 = s.repeat;
813  let mut space: u32 = s.space;
814  let mut i = s.sub_loop_counter;
815  for code_length_code_order in
816      fast!((kCodeLengthCodeOrder)[s.sub_loop_counter as usize; CODE_LENGTH_CODES]).iter() {
817    let code_len_idx = *code_length_code_order;
818    let mut ix: u32 = 0;
819
820    if !bit_reader::BrotliSafeGetBits(&mut s.br, 4, &mut ix, input) {
821      mark_unlikely();
822      let available_bits: u32 = bit_reader::BrotliGetAvailableBits(&s.br);
823      if (available_bits != 0) {
824        ix = bit_reader::BrotliGetBitsUnmasked(&s.br) as u32 & 0xF;
825      } else {
826        ix = 0;
827      }
828      if (fast!((kCodeLengthPrefixLength)[ix as usize]) as u32 > available_bits) {
829        s.sub_loop_counter = i;
830        s.repeat = num_codes;
831        s.space = space;
832        s.substate_huffman = BrotliRunningHuffmanState::BROTLI_STATE_HUFFMAN_COMPLEX;
833        return BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT;
834      }
835    }
836    BROTLI_LOG_UINT!(ix);
837    let v: u32 = fast!((kCodeLengthPrefixValue)[ix as usize]) as u32;
838    bit_reader::BrotliDropBits(&mut s.br,
839                               fast!((kCodeLengthPrefixLength)[ix as usize]) as u32);
840    fast_mut!((s.code_length_code_lengths)[code_len_idx as usize]) = v as u8;
841    BROTLI_LOG_ARRAY_INDEX!(s.code_length_code_lengths, code_len_idx);
842    if v != 0 {
843      space = space.wrapping_sub(32 >> v);
844      num_codes += 1;
845      fast_mut!((s.code_length_histo)[v as usize]) += 1;
846      if space.wrapping_sub(1) >= 32 {
847        // space is 0 or wrapped around
848        break;
849      }
850    }
851    i += 1;
852  }
853  if (!(num_codes == 1 || space == 0)) {
854    return BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_FORMAT_CL_SPACE;
855  }
856  BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS
857}
858
859
860// Decodes the Huffman tables.
861// There are 2 scenarios:
862// A) Huffman code contains only few symbols (1..4). Those symbols are read
863// directly; their code lengths are defined by the number of symbols.
864// For this scenario 4 - 49 bits will be read.
865//
866// B) 2-phase decoding:
867// B.1) Small Huffman table is decoded; it is specified with code lengths
868// encoded with predefined entropy code. 32 - 74 bits are used.
869// B.2) Decoded table is used to decode code lengths of symbols in resulting
870// Huffman table. In worst case 3520 bits are read.
871//
872fn ReadHuffmanCode<AllocU8: alloc::Allocator<u8>,
873                   AllocU32: alloc::Allocator<u32>,
874                   AllocHC: alloc::Allocator<HuffmanCode>>
875  (mut alphabet_size: u32,
876   max_symbol: u32,
877   table: &mut [HuffmanCode],
878   offset: usize,
879   opt_table_size: Option<&mut u32>,
880   s: &mut BrotliState<AllocU8, AllocU32, AllocHC>,
881   input: &[u8])
882   -> BrotliDecoderErrorCode {
883  if offset > table.len() {
884    return BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_FORMAT_HUFFMAN_SPACE;
885  }
886  // Unnecessary masking, but might be good for safety.
887  alphabet_size &= 0x7ff;
888  // State machine
889  loop {
890    match s.substate_huffman {
891      BrotliRunningHuffmanState::BROTLI_STATE_HUFFMAN_NONE => {
892        if !bit_reader::BrotliSafeReadBits(&mut s.br, 2, &mut s.sub_loop_counter, input) {
893          return BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT;
894        }
895
896        BROTLI_LOG_UINT!(s.sub_loop_counter);
897        // The value is used as follows:
898        // 1 for simple code;
899        // 0 for no skipping, 2 skips 2 code lengths, 3 skips 3 code lengths
900        if (s.sub_loop_counter != 1) {
901          s.space = 32;
902          s.repeat = 0; /* num_codes */
903          let max_code_len_len = huffman::BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH as usize + 1;
904          for code_length_histo in fast_mut!((s.code_length_histo)[0;max_code_len_len]).iter_mut() {
905            *code_length_histo = 0; // memset
906          }
907          for code_length_code_length in s.code_length_code_lengths[..].iter_mut() {
908            *code_length_code_length = 0;
909          }
910          s.substate_huffman = BrotliRunningHuffmanState::BROTLI_STATE_HUFFMAN_COMPLEX;
911          // goto Complex;
912          continue;
913        }
914        s.substate_huffman = BrotliRunningHuffmanState::BROTLI_STATE_HUFFMAN_SIMPLE_SIZE;
915        // No break, transit to the next state.
916      }
917      BrotliRunningHuffmanState::BROTLI_STATE_HUFFMAN_SIMPLE_SIZE => {
918        // Read symbols, codes & code lengths directly.
919        if (!bit_reader::BrotliSafeReadBits(&mut s.br, 2, &mut s.symbol, input)) {
920          // num_symbols
921          s.substate_huffman = BrotliRunningHuffmanState::BROTLI_STATE_HUFFMAN_SIMPLE_SIZE;
922          return BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT;
923        }
924        s.sub_loop_counter = 0;
925        // No break, transit to the next state.
926        s.substate_huffman = BrotliRunningHuffmanState::BROTLI_STATE_HUFFMAN_SIMPLE_READ;
927      }
928      BrotliRunningHuffmanState::BROTLI_STATE_HUFFMAN_SIMPLE_READ => {
929        let result = ReadSimpleHuffmanSymbols(alphabet_size, max_symbol, s, input);
930        match result {
931          BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS => {}
932          _ => return result,
933        }
934        // No break, transit to the next state.
935        s.substate_huffman = BrotliRunningHuffmanState::BROTLI_STATE_HUFFMAN_SIMPLE_BUILD;
936      }
937      BrotliRunningHuffmanState::BROTLI_STATE_HUFFMAN_SIMPLE_BUILD => {
938        let table_size: u32;
939        if (s.symbol == 3) {
940          let mut bits: u32 = 0;
941          if (!bit_reader::BrotliSafeReadBits(&mut s.br, 1, &mut bits, input)) {
942            s.substate_huffman = BrotliRunningHuffmanState::BROTLI_STATE_HUFFMAN_SIMPLE_BUILD;
943            return BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT;
944          }
945          s.symbol += bits;
946        }
947        BROTLI_LOG_UINT!(s.symbol);
948        table_size = huffman::BrotliBuildSimpleHuffmanTable(&mut table[offset..],
949                                                            HUFFMAN_TABLE_BITS as i32,
950                                                            &s.symbols_lists_array[..],
951                                                            s.symbol);
952        if table_size == 0 {
953          return BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_FORMAT_HUFFMAN_SPACE;
954        }
955        if let Some(opt_table_size_ref) = opt_table_size {
956          *opt_table_size_ref = table_size
957        }
958        s.substate_huffman = BrotliRunningHuffmanState::BROTLI_STATE_HUFFMAN_NONE;
959        return BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS;
960      }
961
962      // Decode Huffman-coded code lengths.
963      BrotliRunningHuffmanState::BROTLI_STATE_HUFFMAN_COMPLEX => {
964
965        let result = ReadCodeLengthCodeLengths(s, input);
966        match result {
967          BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS => {}
968          _ => return result,
969        }
970        if !huffman::BrotliBuildCodeLengthsHuffmanTable(
971          &mut s.table,
972          &s.code_length_code_lengths,
973          &s.code_length_histo,
974        ) {
975          return BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_FORMAT_HUFFMAN_SPACE;
976        }
977        for code_length_histo in s.code_length_histo[..].iter_mut() {
978          *code_length_histo = 0; // memset
979        }
980
981        let max_code_length = huffman::BROTLI_HUFFMAN_MAX_CODE_LENGTH as usize + 1;
982        for (i, next_symbol_mut) in fast_mut!((s.next_symbol)[0; max_code_length])
983          .iter_mut()
984          .enumerate() {
985          *next_symbol_mut = i as i32 - (max_code_length as i32);
986          fast_mut!((s.symbols_lists_array)[(s.symbol_lists_index as i32
987                                 + i as i32
988                                 - (max_code_length as i32)) as usize]) = 0xFFFF;
989        }
990
991        s.symbol = 0;
992        s.prev_code_len = kDefaultCodeLength;
993        s.repeat = 0;
994        s.repeat_code_len = 0;
995        s.space = 32768;
996        // No break, transit to the next state.
997        s.substate_huffman = BrotliRunningHuffmanState::BROTLI_STATE_HUFFMAN_LENGTH_SYMBOLS;
998      }
999      BrotliRunningHuffmanState::BROTLI_STATE_HUFFMAN_LENGTH_SYMBOLS => {
1000        let table_size: u32;
1001        let mut result = ReadSymbolCodeLengths(max_symbol, s, input);
1002        if let BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT = result {
1003          result = SafeReadSymbolCodeLengths(max_symbol, s, input)
1004        }
1005        match result {
1006          BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS => {}
1007          _ => return result,
1008        }
1009
1010        if (s.space != 0) {
1011          BROTLI_LOG!("[ReadHuffmanCode] space = %d\n", s.space);
1012          return BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_FORMAT_HUFFMAN_SPACE;
1013        }
1014        table_size = huffman::BrotliBuildHuffmanTable(fast_mut!((table)[offset;]),
1015                                                      HUFFMAN_TABLE_BITS as i32,
1016                                                      &s.symbols_lists_array[..],
1017                                                      s.symbol_lists_index,
1018                                                      &mut s.code_length_histo);
1019        if table_size == 0 {
1020          return BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_FORMAT_HUFFMAN_SPACE;
1021        }
1022        if let Some(opt_table_size_ref) = opt_table_size {
1023          *opt_table_size_ref = table_size
1024        }
1025        s.substate_huffman = BrotliRunningHuffmanState::BROTLI_STATE_HUFFMAN_NONE;
1026        return BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS;
1027      }
1028    }
1029  }
1030}
1031
1032// Decodes a block length by reading 3..39 bits.
1033fn ReadBlockLength(table: &[HuffmanCode],
1034                   br: &mut bit_reader::BrotliBitReader,
1035                   input: &[u8])
1036                   -> u32 {
1037  let code: u32;
1038  let nbits: u32;
1039  code = ReadSymbol(table, br, input);
1040  nbits = fast_ref!((prefix::kBlockLengthPrefixCode)[code as usize]).nbits as u32; /*nbits==2..24*/
1041  fast_ref!((prefix::kBlockLengthPrefixCode)[code as usize]).offset as u32 +
1042  bit_reader::BrotliReadBits(br, nbits, input)
1043}
1044
1045
1046// WARNING: if state is not BROTLI_STATE_READ_BLOCK_LENGTH_NONE, then
1047// reading can't be continued with ReadBlockLength.
1048fn SafeReadBlockLengthIndex(substate_read_block_length: &state::BrotliRunningReadBlockLengthState,
1049                            block_length_index: u32,
1050                            table: &[HuffmanCode],
1051                            mut br: &mut bit_reader::BrotliBitReader,
1052                            input: &[u8])
1053                            -> (bool, u32) {
1054  match *substate_read_block_length {
1055    state::BrotliRunningReadBlockLengthState::BROTLI_STATE_READ_BLOCK_LENGTH_NONE => {
1056      let mut index: u32 = 0;
1057      if (!SafeReadSymbol(table, &mut br, &mut index, input)) {
1058        return (false, 0);
1059      }
1060      (true, index)
1061    }
1062    _ => (true, block_length_index),
1063  }
1064}
1065fn SafeReadBlockLengthFromIndex<
1066    AllocHC : alloc::Allocator<HuffmanCode> >(s : &mut BlockTypeAndLengthState<AllocHC>,
1067                                              br : &mut bit_reader::BrotliBitReader,
1068                                              result : &mut u32,
1069                                              res_index : (bool, u32),
1070                                              input : &[u8]) -> bool{
1071  let (res, index) = res_index;
1072  if !res {
1073    return false;
1074  }
1075  let mut bits: u32 = 0;
1076  let nbits = fast_ref!((prefix::kBlockLengthPrefixCode)[index as usize]).nbits; /* nbits==2..24 */
1077  if (!bit_reader::BrotliSafeReadBits(br, nbits as u32, &mut bits, input)) {
1078    s.block_length_index = index;
1079    s.substate_read_block_length =
1080      state::BrotliRunningReadBlockLengthState::BROTLI_STATE_READ_BLOCK_LENGTH_SUFFIX;
1081    return false;
1082  }
1083  *result = fast_ref!((prefix::kBlockLengthPrefixCode)[index as usize]).offset as u32 + bits;
1084  s.substate_read_block_length =
1085    state::BrotliRunningReadBlockLengthState::BROTLI_STATE_READ_BLOCK_LENGTH_NONE;
1086  true
1087}
1088macro_rules! SafeReadBlockLength (
1089   ($state : expr, $result : expr , $table : expr) => {
1090       SafeReadBlockLengthFromIndex(&mut $state, &mut $result,
1091                                    SafeReadBlockLengthIndex($state.substate_read_block_length,
1092                                                             $state.block_length_index,
1093                                                             $table,
1094                                                             &mut $state.br))
1095   };
1096);
1097
1098// Transform:
1099// 1) initialize list L with values 0, 1,... 255
1100// 2) For each input element X:
1101// 2.1) let Y = L[X]
1102// 2.2) remove X-th element from L
1103// 2.3) prepend Y to L
1104// 2.4) append Y to output
1105//
1106// In most cases max(Y) <= 7, so most of L remains intact.
1107// To reduce the cost of initialization, we reuse L, remember the upper bound
1108// of Y values, and reinitialize only first elements in L.
1109//
1110// Most of input values are 0 and 1. To reduce number of branches, we replace
1111// inner for loop with do-while.
1112//
1113fn InverseMoveToFrontTransform(v: &mut [u8],
1114                               v_len: u32,
1115                               mtf: &mut [u8;256],
1116                               mtf_upper_bound: &mut u32) {
1117  // Reinitialize elements that could have been changed.
1118  let mut upper_bound: u32 = *mtf_upper_bound;
1119  for (i, item) in fast_mut!((mtf)[0;(upper_bound as usize + 1usize)]).iter_mut().enumerate() {
1120    *item = i as u8;
1121  }
1122
1123  // Transform the input.
1124  upper_bound = 0;
1125  for v_i in fast_mut!((v)[0usize ; (v_len as usize)]).iter_mut() {
1126    let mut index = (*v_i) as i32;
1127    let value = fast!((mtf)[index as usize]);
1128    upper_bound |= (*v_i) as u32;
1129    *v_i = value;
1130    if index <= 0 {
1131      fast_mut!((mtf)[0]) = 0;
1132    } else {
1133      loop {
1134        index -= 1;
1135        fast_mut!((mtf)[(index + 1) as usize]) = fast!((mtf)[index as usize]);
1136        if index <= 0 {
1137          break;
1138        }
1139      }
1140    }
1141    fast_mut!((mtf)[0]) = value;
1142  }
1143  // Remember amount of elements to be reinitialized.
1144  *mtf_upper_bound = upper_bound;
1145}
1146// Decodes a series of Huffman table using ReadHuffmanCode function.
1147fn HuffmanTreeGroupDecode<AllocU8: alloc::Allocator<u8>,
1148                          AllocU32: alloc::Allocator<u32>,
1149                          AllocHC: alloc::Allocator<HuffmanCode>>
1150  (group_index: i32,
1151   mut s: &mut BrotliState<AllocU8, AllocU32, AllocHC>,
1152   input: &[u8])
1153   -> BrotliDecoderErrorCode {
1154  let mut hcodes: AllocHC::AllocatedMemory;
1155  let mut htrees: AllocU32::AllocatedMemory;
1156  let alphabet_size: u16;
1157  let group_num_htrees: u16;
1158  let group_max_symbol;
1159  if group_index == 0 {
1160    hcodes = mem::replace(&mut s.literal_hgroup.codes,
1161                          AllocHC::AllocatedMemory::default());
1162    htrees = mem::replace(&mut s.literal_hgroup.htrees,
1163                          AllocU32::AllocatedMemory::default());
1164    group_num_htrees = s.literal_hgroup.num_htrees;
1165    alphabet_size = s.literal_hgroup.alphabet_size;
1166    group_max_symbol = s.literal_hgroup.max_symbol;
1167  } else if group_index == 1 {
1168    hcodes = mem::replace(&mut s.insert_copy_hgroup.codes,
1169                          AllocHC::AllocatedMemory::default());
1170    htrees = mem::replace(&mut s.insert_copy_hgroup.htrees,
1171                          AllocU32::AllocatedMemory::default());
1172    group_num_htrees = s.insert_copy_hgroup.num_htrees;
1173    alphabet_size = s.insert_copy_hgroup.alphabet_size;
1174    group_max_symbol = s.insert_copy_hgroup.max_symbol;
1175  } else {
1176    if group_index != 2 {
1177      let ret = BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_UNREACHABLE;
1178      SaveErrorCode!(s, ret);
1179      return ret;
1180    }
1181    hcodes = mem::replace(&mut s.distance_hgroup.codes,
1182                          AllocHC::AllocatedMemory::default());
1183    htrees = mem::replace(&mut s.distance_hgroup.htrees,
1184                          AllocU32::AllocatedMemory::default());
1185    group_num_htrees = s.distance_hgroup.num_htrees;
1186    alphabet_size = s.distance_hgroup.alphabet_size;
1187    group_max_symbol = s.distance_hgroup.max_symbol;
1188  }
1189  match s.substate_tree_group {
1190    BrotliRunningTreeGroupState::BROTLI_STATE_TREE_GROUP_NONE => {
1191      s.htree_next_offset = 0;
1192      s.htree_index = 0;
1193      s.substate_tree_group = BrotliRunningTreeGroupState::BROTLI_STATE_TREE_GROUP_LOOP;
1194    }
1195    BrotliRunningTreeGroupState::BROTLI_STATE_TREE_GROUP_LOOP => {}
1196  }
1197  let mut result = BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS;
1198  for htree_iter in
1199      fast_mut!((htrees.slice_mut())[s.htree_index as usize ; (group_num_htrees as usize)])
1200    .iter_mut() {
1201    let mut table_size: u32 = 0;
1202    result = ReadHuffmanCode(u32::from(alphabet_size), u32::from(group_max_symbol),
1203                             hcodes.slice_mut(),
1204                             s.htree_next_offset as usize,
1205                             Some(&mut table_size),
1206                             &mut s,
1207                             input);
1208    match result {
1209      BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS => {}
1210      _ => break, // break and return the result code
1211    }
1212    *htree_iter = s.htree_next_offset;
1213    s.htree_next_offset += table_size;
1214    s.htree_index += 1;
1215  }
1216  if group_index == 0 {
1217    let _ = mem::replace(&mut s.literal_hgroup.codes,
1218                 mem::replace(&mut hcodes, AllocHC::AllocatedMemory::default()));
1219    let _ = mem::replace(&mut s.literal_hgroup.htrees,
1220                 mem::replace(&mut htrees, AllocU32::AllocatedMemory::default()));
1221  } else if group_index == 1 {
1222    let _ = mem::replace(&mut s.insert_copy_hgroup.codes,
1223                 mem::replace(&mut hcodes, AllocHC::AllocatedMemory::default()));
1224    let _ = mem::replace(&mut s.insert_copy_hgroup.htrees,
1225                 mem::replace(&mut htrees, AllocU32::AllocatedMemory::default()));
1226  } else {
1227    let _ = mem::replace(&mut s.distance_hgroup.codes,
1228                 mem::replace(&mut hcodes, AllocHC::AllocatedMemory::default()));
1229    let _ = mem::replace(&mut s.distance_hgroup.htrees,
1230                 mem::replace(&mut htrees, AllocU32::AllocatedMemory::default()));
1231  }
1232  if let BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS = result {
1233    s.substate_tree_group = BrotliRunningTreeGroupState::BROTLI_STATE_TREE_GROUP_NONE
1234  }
1235  result
1236}
1237#[allow(dead_code)]
1238pub fn lg_window_size(first_byte: u8, second_byte: u8) -> Result<(u8, u8), ()> {
1239  if first_byte & 1 == 0 {
1240    return Ok((16, 1));
1241  }
1242  match first_byte & 15 {
1243    0x3 => return Ok((18, 4)),
1244    0x5 => return Ok((19, 4)),
1245    0x7 => return Ok((20, 4)),
1246    0x9 => return Ok((21, 4)),
1247    0xb => return Ok((22, 4)),
1248    0xd => return Ok((23, 4)),
1249    0xf => return Ok((24, 4)),
1250    _ => match first_byte & 127 {
1251      0x71 => return Ok((15, 7)),
1252      0x61 => return Ok((14, 7)),
1253      0x51 => return Ok((13, 7)),
1254      0x41 => return Ok((12, 7)),
1255      0x31 => return Ok((11, 7)),
1256      0x21 => return Ok((10, 7)),
1257      0x1 => return Ok((17, 7)),
1258      _ => {},
1259    }
1260  }
1261  if (first_byte & 0x80) != 0 {
1262    return Err(());
1263  }
1264  let ret  = second_byte & 0x3f;
1265  if ret < 10 || ret > 30 {
1266    return Err(());
1267  }
1268  Ok((ret, 14))
1269
1270}
1271
1272
1273fn bzero(data: &mut [u8]) {
1274  for iter in data.iter_mut() {
1275    *iter = 0;
1276  }
1277}
1278
1279
1280// Decodes a context map.
1281// Decoding is done in 4 phases:
1282// 1) Read auxiliary information (6..16 bits) and allocate memory.
1283// In case of trivial context map, decoding is finished at this phase.
1284// 2) Decode Huffman table using ReadHuffmanCode function.
1285// This table will be used for reading context map items.
1286// 3) Read context map items; "0" values could be run-length encoded.
1287// 4) Optionally, apply InverseMoveToFront transform to the resulting map.
1288//
1289fn DecodeContextMapInner<AllocU8: alloc::Allocator<u8>,
1290                         AllocU32: alloc::Allocator<u32>,
1291                         AllocHC: alloc::Allocator<HuffmanCode>>
1292  (context_map_size: u32,
1293   num_htrees: &mut u32,
1294   context_map_arg: &mut AllocU8::AllocatedMemory,
1295   mut s: &mut BrotliState<AllocU8, AllocU32, AllocHC>,
1296   input: &[u8])
1297   -> BrotliDecoderErrorCode {
1298
1299  let mut result;
1300  loop {
1301    match s.substate_context_map {
1302      BrotliRunningContextMapState::BROTLI_STATE_CONTEXT_MAP_NONE => {
1303        result = DecodeVarLenUint8(&mut s.substate_decode_uint8, &mut s.br, num_htrees, input);
1304        match result {
1305          BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS => {}
1306          _ => return result,
1307        }
1308        (*num_htrees) += 1;
1309        s.context_index = 0;
1310        BROTLI_LOG_UINT!(context_map_size);
1311        BROTLI_LOG_UINT!(*num_htrees);
1312        *context_map_arg = s.alloc_u8.alloc_cell(context_map_size as usize);
1313        if (context_map_arg.slice().len() < context_map_size as usize) {
1314          return BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MAP;
1315        }
1316        if (*num_htrees <= 1) {
1317          // This happens automatically but we do it to retain C++ similarity:
1318          bzero(context_map_arg.slice_mut()); // necessary if we compiler with unsafe feature flag
1319          return BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS;
1320        }
1321        s.substate_context_map = BrotliRunningContextMapState::BROTLI_STATE_CONTEXT_MAP_READ_PREFIX;
1322        // No break, continue to next state.
1323      }
1324      BrotliRunningContextMapState::BROTLI_STATE_CONTEXT_MAP_READ_PREFIX => {
1325        let mut bits: u32 = 0;
1326        // In next stage ReadHuffmanCode uses at least 4 bits, so it is safe
1327        // to peek 4 bits ahead.
1328        if (!bit_reader::BrotliSafeGetBits(&mut s.br, 5, &mut bits, input)) {
1329          return BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT;
1330        }
1331        if ((bits & 1) != 0) {
1332          // Use RLE for zeroes.
1333          s.max_run_length_prefix = (bits >> 1) + 1;
1334          bit_reader::BrotliDropBits(&mut s.br, 5);
1335        } else {
1336          s.max_run_length_prefix = 0;
1337          bit_reader::BrotliDropBits(&mut s.br, 1);
1338        }
1339        BROTLI_LOG_UINT!(s.max_run_length_prefix);
1340        s.substate_context_map = BrotliRunningContextMapState::BROTLI_STATE_CONTEXT_MAP_HUFFMAN;
1341        // No break, continue to next state.
1342      }
1343      BrotliRunningContextMapState::BROTLI_STATE_CONTEXT_MAP_HUFFMAN => {
1344
1345        let mut local_context_map_table = mem::replace(&mut s.context_map_table,
1346                                                       AllocHC::AllocatedMemory::default());
1347        let alphabet_size = *num_htrees + s.max_run_length_prefix;
1348        result = ReadHuffmanCode(alphabet_size, alphabet_size,
1349                                 &mut local_context_map_table.slice_mut(),
1350                                 0,
1351                                 None,
1352                                 &mut s,
1353                                 input);
1354        let _ = mem::replace(&mut s.context_map_table,
1355                     mem::replace(&mut local_context_map_table,
1356                                  AllocHC::AllocatedMemory::default()));
1357        match result {
1358          BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS => {}
1359          _ => return result,
1360        }
1361        s.code = 0xFFFF;
1362        s.substate_context_map = BrotliRunningContextMapState::BROTLI_STATE_CONTEXT_MAP_DECODE;
1363        // No break, continue to next state.
1364      }
1365      BrotliRunningContextMapState::BROTLI_STATE_CONTEXT_MAP_DECODE => {
1366        let mut context_index: u32 = s.context_index;
1367        let max_run_length_prefix: u32 = s.max_run_length_prefix;
1368        let context_map = &mut context_map_arg.slice_mut();
1369        let mut code: u32 = s.code;
1370        let mut rleCodeGoto = (code != 0xFFFF);
1371        while (rleCodeGoto || context_index < context_map_size) {
1372          if !rleCodeGoto {
1373            if (!SafeReadSymbol(s.context_map_table.slice(), &mut s.br, &mut code, input)) {
1374              s.code = 0xFFFF;
1375              s.context_index = context_index;
1376              return BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT;
1377            }
1378            BROTLI_LOG_UINT!(code);
1379
1380            if code == 0 {
1381              fast_mut!((context_map)[context_index as usize]) = 0;
1382              BROTLI_LOG_ARRAY_INDEX!(context_map, context_index as usize);
1383              context_index += 1;
1384              continue;
1385            }
1386            if code > max_run_length_prefix {
1387              fast_mut!((context_map)[context_index as usize]) =
1388                (code - max_run_length_prefix) as u8;
1389              BROTLI_LOG_ARRAY_INDEX!(context_map, context_index as usize);
1390              context_index += 1;
1391              continue;
1392            }
1393          }
1394          rleCodeGoto = false; // <- this was a goto beforehand... now we have reached label
1395          // we are treated like everyday citizens from this point forth
1396          {
1397            let mut reps: u32 = 0;
1398            if (!bit_reader::BrotliSafeReadBits(&mut s.br, code, &mut reps, input)) {
1399              s.code = code;
1400              s.context_index = context_index;
1401              return BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT;
1402            }
1403            reps += 1u32 << code;
1404            BROTLI_LOG_UINT!(reps);
1405            if (context_index + reps > context_map_size) {
1406              return BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_FORMAT_CONTEXT_MAP_REPEAT;
1407            }
1408            loop {
1409              fast_mut!((context_map)[context_index as usize]) = 0;
1410              BROTLI_LOG_ARRAY_INDEX!(context_map, context_index as usize);
1411              context_index += 1;
1412              reps -= 1;
1413              if reps == 0 {
1414                break;
1415              }
1416            }
1417          }
1418        }
1419        // No break, continue to next state.
1420        s.substate_context_map = BrotliRunningContextMapState::BROTLI_STATE_CONTEXT_MAP_TRANSFORM;
1421      }
1422      BrotliRunningContextMapState::BROTLI_STATE_CONTEXT_MAP_TRANSFORM => {
1423        let mut bits: u32 = 0;
1424        if (!bit_reader::BrotliSafeReadBits(&mut s.br, 1, &mut bits, input)) {
1425          s.substate_context_map = BrotliRunningContextMapState::BROTLI_STATE_CONTEXT_MAP_TRANSFORM;
1426          return BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT;
1427        }
1428        if (bits != 0) {
1429          if let Ok(ref mut mtf) = s.mtf_or_error_string {
1430            InverseMoveToFrontTransform(context_map_arg.slice_mut(),
1431                                        context_map_size,
1432                                        mtf,
1433                                        &mut s.mtf_upper_bound);
1434          } else {
1435            // the error state is stored here--we can't make it this deep with an active error
1436            return BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_UNREACHABLE;
1437          }
1438        }
1439        s.substate_context_map = BrotliRunningContextMapState::BROTLI_STATE_CONTEXT_MAP_NONE;
1440        return BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS;
1441      }
1442    }
1443  }
1444  // unreachable!(); (compiler will error if it's reachable due to the unit return type)
1445}
1446
1447fn DecodeContextMap<AllocU8: alloc::Allocator<u8>,
1448                    AllocU32: alloc::Allocator<u32>,
1449                    AllocHC: alloc::Allocator<HuffmanCode>>
1450  (context_map_size: usize,
1451   is_dist_context_map: bool,
1452   mut s: &mut BrotliState<AllocU8, AllocU32, AllocHC>,
1453   input: &[u8])
1454   -> BrotliDecoderErrorCode {
1455
1456  match s.state {
1457    BrotliRunningState::BROTLI_STATE_CONTEXT_MAP_1 if !is_dist_context_map => {},
1458    BrotliRunningState::BROTLI_STATE_CONTEXT_MAP_2 if is_dist_context_map => {},
1459    _ => return BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_UNREACHABLE,
1460  }
1461  let (mut num_htrees, mut context_map_arg) = if is_dist_context_map {
1462    (s.num_dist_htrees, mem::replace(&mut s.dist_context_map, AllocU8::AllocatedMemory::default()))
1463  } else {
1464    (s.num_literal_htrees, mem::replace(&mut s.context_map, AllocU8::AllocatedMemory::default()))
1465  };
1466
1467  let retval = DecodeContextMapInner(context_map_size as u32,
1468                                     &mut num_htrees,
1469                                     &mut context_map_arg,
1470                                     &mut s,
1471                                     input);
1472  if is_dist_context_map {
1473    s.num_dist_htrees = num_htrees;
1474    let _ = mem::replace(&mut s.dist_context_map,
1475                 mem::replace(&mut context_map_arg, AllocU8::AllocatedMemory::default()));
1476  } else {
1477    s.num_literal_htrees = num_htrees;
1478    let _ = mem::replace(&mut s.context_map,
1479                 mem::replace(&mut context_map_arg, AllocU8::AllocatedMemory::default()));
1480  }
1481  retval
1482}
1483
1484// Decodes a command or literal and updates block type ringbuffer.
1485// Reads 3..54 bits.
1486fn DecodeBlockTypeAndLength<
1487  AllocHC : alloc::Allocator<HuffmanCode>> (safe : bool,
1488                                            s : &mut BlockTypeAndLengthState<AllocHC>,
1489                                            br : &mut bit_reader::BrotliBitReader,
1490                                            tree_type : i32,
1491                                            input : &[u8]) -> bool {
1492  let max_block_type = fast!((s.num_block_types)[tree_type as usize]);
1493  let tree_offset = tree_type as usize * huffman::BROTLI_HUFFMAN_MAX_TABLE_SIZE as usize;
1494
1495  let mut block_type: u32 = 0;
1496  if max_block_type <= 1 {
1497    return false;
1498  }
1499  // Read 0..15 + 3..39 bits
1500  if (!safe) {
1501    block_type = ReadSymbol(fast_slice!((s.block_type_trees)[tree_offset;]), br, input);
1502    fast_mut!((s.block_length)[tree_type as usize]) =
1503      ReadBlockLength(fast_slice!((s.block_len_trees)[tree_offset;]), br, input);
1504  } else {
1505    let memento = bit_reader::BrotliBitReaderSaveState(br);
1506    if (!SafeReadSymbol(fast_slice!((s.block_type_trees)[tree_offset;]),
1507                        br,
1508                        &mut block_type,
1509                        input)) {
1510      return false;
1511    }
1512    let mut block_length_out: u32 = 0;
1513
1514    let index_ret = SafeReadBlockLengthIndex(&s.substate_read_block_length,
1515                                             s.block_length_index,
1516                                             fast_slice!((s.block_len_trees)[tree_offset;]),
1517                                             br,
1518                                             input);
1519    if !SafeReadBlockLengthFromIndex(s, br, &mut block_length_out, index_ret, input) {
1520      s.substate_read_block_length =
1521        BrotliRunningReadBlockLengthState::BROTLI_STATE_READ_BLOCK_LENGTH_NONE;
1522      bit_reader::BrotliBitReaderRestoreState(br, &memento);
1523      return false;
1524    }
1525    fast_mut!((s.block_length)[tree_type as usize]) = block_length_out;
1526  }
1527  let ringbuffer: &mut [u32] = &mut fast_mut!((s.block_type_rb)[tree_type as usize * 2;]);
1528  if (block_type == 1) {
1529    block_type = fast!((ringbuffer)[1]) + 1;
1530  } else if (block_type == 0) {
1531    block_type = fast!((ringbuffer)[0]);
1532  } else {
1533    block_type -= 2;
1534  }
1535  if (block_type >= max_block_type) {
1536    block_type -= max_block_type;
1537  }
1538  fast_mut!((ringbuffer)[0]) = fast!((ringbuffer)[1]);
1539  fast_mut!((ringbuffer)[1]) = block_type;
1540  true
1541}
1542fn DetectTrivialLiteralBlockTypes<AllocU8: alloc::Allocator<u8>,
1543                                  AllocU32: alloc::Allocator<u32>,
1544                                  AllocHC: alloc::Allocator<HuffmanCode>>
1545  (s: &mut BrotliState<AllocU8, AllocU32, AllocHC>) {
1546  for iter in s.trivial_literal_contexts.iter_mut() {
1547    *iter = 0;
1548  }
1549  let mut i: usize = 0;
1550  while i < fast!((s.block_type_length_state.num_block_types)[0]) as usize {
1551    let offset = (i as usize) << kLiteralContextBits;
1552    let mut error = 0usize;
1553    let sample: usize = fast_slice!((s.context_map)[offset]) as usize;
1554    let mut j = 0usize;
1555    while j < ((1 as usize) << kLiteralContextBits) {
1556      error |= fast_slice!((s.context_map)[offset + j]) as usize ^ sample;
1557      j += 1;
1558      error |= fast_slice!((s.context_map)[offset + j]) as usize ^ sample;
1559      j += 1;
1560      error |= fast_slice!((s.context_map)[offset + j]) as usize ^ sample;
1561      j += 1;
1562      error |= fast_slice!((s.context_map)[offset + j]) as usize ^ sample;
1563      j += 1
1564    }
1565    if error == 0 {
1566      s.trivial_literal_contexts[i >> 5] |= ((1 as u32) << (i & 31));
1567    }
1568    i += 1
1569  }
1570}
1571fn PrepareLiteralDecoding<AllocU8: alloc::Allocator<u8>,
1572                          AllocU32: alloc::Allocator<u32>,
1573                          AllocHC: alloc::Allocator<HuffmanCode>>
1574  (s: &mut BrotliState<AllocU8, AllocU32, AllocHC>) {
1575
1576  let context_offset: u32;
1577  let block_type = fast!((s.block_type_length_state.block_type_rb)[1]) as usize;
1578  context_offset = (block_type << kLiteralContextBits) as u32;
1579  s.context_map_slice_index = context_offset as usize;
1580  let trivial = fast!((s.trivial_literal_contexts)[block_type >> 5]);
1581  s.trivial_literal_context = ((trivial >> (block_type & 31)) & 1) as i32;
1582
1583  s.literal_htree_index = fast_slice!((s.context_map)[s.context_map_slice_index]);
1584  // s.literal_htree = fast!((s.literal_hgroup.htrees)[s.literal_htree_index]); // redundant
1585  let context_mode_index = fast!((s.context_modes.slice())[block_type]) & 3;
1586  s.context_lookup = &kContextLookup[context_mode_index as usize];
1587}
1588
1589// Decodes the block ty
1590// pe and updates the state for literal context.
1591// Reads 3..54 bits.
1592fn DecodeLiteralBlockSwitchInternal<AllocU8: alloc::Allocator<u8>,
1593                                    AllocU32: alloc::Allocator<u32>,
1594                                    AllocHC: alloc::Allocator<HuffmanCode>>
1595  (safe: bool,
1596   s: &mut BrotliState<AllocU8, AllocU32, AllocHC>,
1597   input: &[u8])
1598   -> bool {
1599
1600  if !DecodeBlockTypeAndLength(safe, &mut s.block_type_length_state, &mut s.br, 0, input) {
1601    return false;
1602  }
1603  PrepareLiteralDecoding(s);
1604  true
1605}
1606// fn DecodeLiteralBlockSwitch<
1607// 'a,
1608// AllocU8 : alloc::Allocator<u8>,
1609// AllocU32 : alloc::Allocator<u32>,
1610// AllocHC : alloc::Allocator<HuffmanCode>> (safe : bool,
1611// mut s : &mut BrotliState<AllocU8, AllocU32, AllocHC>) {
1612// DecodeLiteralBlockSwitchInternal(false, s);
1613// }
1614//
1615// fn SafeDecodeLiteralBlockSwitch<
1616// 'a,
1617// AllocU8 : alloc::Allocator<u8>,
1618// AllocU32 : alloc::Allocator<u32>,
1619// AllocHC : alloc::Allocator<HuffmanCode>> (safe : bool,
1620// mut s : &mut BrotliState<AllocU8, AllocU32, AllocHC>) -> bool {
1621// return DecodeLiteralBlockSwitchInternal(true, s);
1622// }
1623//
1624// Block switch for insert/copy length.
1625// Reads 3..54 bits.
1626fn DecodeCommandBlockSwitchInternal<AllocU8: alloc::Allocator<u8>,
1627                                    AllocU32: alloc::Allocator<u32>,
1628                                    AllocHC: alloc::Allocator<HuffmanCode>>
1629  (safe: bool,
1630   s: &mut BrotliState<AllocU8, AllocU32, AllocHC>,
1631   input: &[u8])
1632   -> bool {
1633  if (!DecodeBlockTypeAndLength(safe, &mut s.block_type_length_state, &mut s.br, 1, input)) {
1634    return false;
1635  }
1636  s.htree_command_index = fast!((s.block_type_length_state.block_type_rb)[3]) as u16;
1637  true
1638}
1639
1640#[allow(dead_code)]
1641fn DecodeCommandBlockSwitch<AllocU8: alloc::Allocator<u8>,
1642                            AllocU32: alloc::Allocator<u32>,
1643                            AllocHC: alloc::Allocator<HuffmanCode>>
1644  (s: &mut BrotliState<AllocU8, AllocU32, AllocHC>,
1645   input: &[u8]) {
1646  DecodeCommandBlockSwitchInternal(false, s, input);
1647}
1648#[allow(dead_code)]
1649fn SafeDecodeCommandBlockSwitch<AllocU8: alloc::Allocator<u8>,
1650                                AllocU32: alloc::Allocator<u32>,
1651                                AllocHC: alloc::Allocator<HuffmanCode>>
1652  (s: &mut BrotliState<AllocU8, AllocU32, AllocHC>,
1653   input: &[u8])
1654   -> bool {
1655  DecodeCommandBlockSwitchInternal(true, s, input)
1656}
1657
1658// Block switch for distance codes.
1659// Reads 3..54 bits.
1660fn DecodeDistanceBlockSwitchInternal<AllocU8: alloc::Allocator<u8>,
1661                                     AllocU32: alloc::Allocator<u32>,
1662                                     AllocHC: alloc::Allocator<HuffmanCode>>
1663  (safe: bool,
1664   s: &mut BrotliState<AllocU8, AllocU32, AllocHC>,
1665   input: &[u8])
1666   -> bool {
1667  if (!DecodeBlockTypeAndLength(safe, &mut s.block_type_length_state, &mut s.br, 2, input)) {
1668    return false;
1669  }
1670  s.dist_context_map_slice_index =
1671    (fast!((s.block_type_length_state.block_type_rb)[5]) << kDistanceContextBits) as usize;
1672  s.dist_htree_index = fast_slice!((s.dist_context_map)[s.dist_context_map_slice_index
1673                                                  + s.distance_context as usize]);
1674  true
1675}
1676
1677#[allow(dead_code)]
1678fn DecodeDistanceBlockSwitch<AllocU8: alloc::Allocator<u8>,
1679                             AllocU32: alloc::Allocator<u32>,
1680                             AllocHC: alloc::Allocator<HuffmanCode>>
1681  (s: &mut BrotliState<AllocU8, AllocU32, AllocHC>,
1682   input: &[u8]) {
1683  DecodeDistanceBlockSwitchInternal(false, s, input);
1684}
1685
1686#[allow(dead_code)]
1687fn SafeDecodeDistanceBlockSwitch<AllocU8: alloc::Allocator<u8>,
1688                                 AllocU32: alloc::Allocator<u32>,
1689                                 AllocHC: alloc::Allocator<HuffmanCode>>
1690  (s: &mut BrotliState<AllocU8, AllocU32, AllocHC>,
1691   input: &[u8])
1692   -> bool {
1693  DecodeDistanceBlockSwitchInternal(true, s, input)
1694}
1695
1696// Bytes decoded into the ring buffer but not yet handed to the caller.
1697// Callers must have established CheckRingBufferConsistency.
1698fn UnwrittenBytes<AllocU8: alloc::Allocator<u8>,
1699                  AllocU32: alloc::Allocator<u32>,
1700                  AllocHC: alloc::Allocator<HuffmanCode>> (
1701  s: &BrotliState<AllocU8, AllocU32, AllocHC>,
1702  wrap: bool,
1703)  -> u64 {
1704  debug_assert!(s.pos >= 0 && s.ringbuffer_size > 0);
1705  let ringbuffer_size = s.ringbuffer_size as u64;
1706  let pos = if wrap && s.pos > s.ringbuffer_size {
1707    ringbuffer_size
1708  } else {
1709    s.pos as u64
1710  };
1711  let partial_pos_rb = s.rb_roundtrips * ringbuffer_size + pos;
1712  debug_assert!(partial_pos_rb >= s.partial_pos_out);
1713  partial_pos_rb - s.partial_pos_out
1714}
1715
1716// The invariant every ring-buffer read depends on: a positive size matching the
1717// mask, and a `pos` inside the allocation. Only a decoder bug can break it, but
1718// it stays a runtime check because the `unsafe` build would read out of bounds
1719// rather than panic.
1720fn CheckRingBufferConsistency<AllocU8: alloc::Allocator<u8>,
1721                              AllocU32: alloc::Allocator<u32>,
1722                              AllocHC: alloc::Allocator<HuffmanCode>>(
1723  s: &BrotliState<AllocU8, AllocU32, AllocHC>,
1724) -> bool {
1725  s.pos >= 0 && s.ringbuffer_size > 0 && s.ringbuffer_mask >= 0 &&
1726    s.ringbuffer_mask as i64 + 1 == s.ringbuffer_size as i64 &&
1727    s.ringbuffer_size as usize <= s.ringbuffer.slice().len()
1728}
1729fn WriteRingBuffer<'a,
1730                   AllocU8: alloc::Allocator<u8>,
1731                   AllocU32: alloc::Allocator<u32>,
1732                   AllocHC: alloc::Allocator<HuffmanCode>>(
1733  available_out: &mut usize,
1734  opt_output: Option<&mut [u8]>,
1735  output_offset: &mut usize,
1736  total_out: &mut usize,
1737  force: bool,
1738  s: &'a mut BrotliState<AllocU8, AllocU32, AllocHC>,
1739) -> (BrotliDecoderErrorCode, &'a [u8]) {
1740  if s.meta_block_remaining_len < 0 {
1741    return (BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_1, &[]);
1742  }
1743  if !CheckRingBufferConsistency(s) {
1744    return (BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_UNREACHABLE, &[]);
1745  }
1746  // window_bits is 9..=24, or 10..=30 for large-window streams; masked so the
1747  // shift stays in range regardless.
1748  debug_assert!(s.window_bits < 64);
1749  let window_size = 1i64 << (s.window_bits & 63);
1750  let to_write = UnwrittenBytes(s, true);
1751  let num_written = core::cmp::min(*available_out as u64, to_write) as usize;
1752  let start_index = (s.partial_pos_out & s.ringbuffer_mask as u64) as usize;
1753  let start = match s.ringbuffer.slice().get(start_index..start_index + num_written) {
1754    Some(start) => start,
1755    None => return (BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_UNREACHABLE, &[]),
1756  };
1757  // output is caller-supplied, hence INVALID_ARGUMENTS rather than UNREACHABLE.
1758  let output_end = match (*output_offset).checked_add(num_written) {
1759    Some(output_end) => output_end,
1760    None => return (BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_INVALID_ARGUMENTS, &[]),
1761  };
1762  if let Some(output) = opt_output {
1763    match output.get_mut(*output_offset..output_end) {
1764      Some(output_slice) => output_slice.clone_from_slice(start),
1765      None => return (BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_INVALID_ARGUMENTS, &[]),
1766    }
1767  }
1768  *output_offset = output_end;
1769  *available_out -= num_written;
1770  BROTLI_LOG_UINT!(to_write);
1771  BROTLI_LOG_UINT!(num_written);
1772  s.partial_pos_out += num_written as u64;
1773  // The public API reports total_out as usize, matching C's size_t: on a 32-bit
1774  // target it truncates past 4GiB, while the internal accounting does not.
1775  *total_out = s.partial_pos_out as usize;
1776  if (num_written as u64) < to_write {
1777    if s.ringbuffer_size as i64 == window_size || force {
1778      // TakeOutput still needs the bytes consumed by this partial write.
1779      return (BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_OUTPUT, start);
1780    } else {
1781      return (BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS, start);
1782    }
1783  }
1784  if (s.ringbuffer_size as i64 == window_size &&
1785      s.pos >= s.ringbuffer_size) {
1786    s.pos -= s.ringbuffer_size;
1787    s.rb_roundtrips += 1;
1788    s.should_wrap_ringbuffer = s.pos != 0;
1789  }
1790  (BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS, start)
1791 }
1792
1793fn WrapRingBuffer<AllocU8: alloc::Allocator<u8>,
1794                   AllocU32: alloc::Allocator<u32>,
1795                   AllocHC: alloc::Allocator<HuffmanCode>>(
1796  s: &mut BrotliState<AllocU8, AllocU32, AllocHC>,
1797) -> bool {
1798  if s.should_wrap_ringbuffer {
1799    if s.ringbuffer_size < 0 || s.pos < 0 {
1800      return false;
1801    }
1802    let ringbuffer_size = s.ringbuffer_size as usize;
1803    let pos = s.pos as usize;
1804    let ringbuffer_len = s.ringbuffer.slice().len();
1805    // A transformed custom-dictionary word can overshoot the end by at most
1806    // 540 bytes (255-byte prefix + 31-byte word + 255-byte suffix, starting at
1807    // the final ring-buffer byte), which is why `pos` may exceed
1808    // `ringbuffer_size`. Wrapping is only done at the full window size, whose
1809    // minimum is 1 << kBrotliLargeMinWbits == 1024, and the tail region is
1810    // kRingBufferWriteAheadSlack + kBrotliMaxDictionaryWordLength bytes long.
1811    if ringbuffer_size > ringbuffer_len ||
1812       pos > ringbuffer_size ||
1813       pos > ringbuffer_len - ringbuffer_size {
1814      return false;
1815    }
1816    let (ring_buffer_start, ring_buffer_end) =
1817      s.ringbuffer.slice_mut().split_at_mut(ringbuffer_size);
1818    ring_buffer_start[..pos].clone_from_slice(&ring_buffer_end[..pos]);
1819    s.should_wrap_ringbuffer = false;
1820  }
1821  true
1822}
1823
1824fn CopyUncompressedBlockToOutput<AllocU8: alloc::Allocator<u8>,
1825                                 AllocU32: alloc::Allocator<u32>,
1826                                 AllocHC: alloc::Allocator<HuffmanCode>>
1827  (mut available_out: &mut usize,
1828   mut output: &mut [u8],
1829   mut output_offset: &mut usize,
1830   mut total_out: &mut usize,
1831   mut s: &mut BrotliState<AllocU8, AllocU32, AllocHC>,
1832   input: &[u8])
1833   -> BrotliDecoderErrorCode {
1834  // State machine
1835  loop {
1836    match s.substate_uncompressed {
1837      BrotliRunningUncompressedState::BROTLI_STATE_UNCOMPRESSED_NONE => {
1838        let remaining = bit_reader::BrotliGetRemainingBytes(&s.br);
1839        let mut nbytes = core::cmp::min(remaining, s.meta_block_remaining_len as u32);
1840        nbytes = core::cmp::min(nbytes, (s.ringbuffer_size - s.pos) as u32);
1841        // Copy remaining bytes from s.br.buf_ to ringbuffer.
1842        bit_reader::BrotliCopyBytes(fast_mut!((s.ringbuffer.slice_mut())[s.pos as usize;]),
1843                                    &mut s.br,
1844                                    nbytes,
1845                                    input);
1846        s.pos += nbytes as i32;
1847        s.meta_block_remaining_len -= nbytes as i32;
1848        if s.pos < (1 << s.window_bits) {
1849          if (s.meta_block_remaining_len == 0) {
1850            return BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS;
1851          }
1852          return BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT;
1853        }
1854        s.substate_uncompressed = BrotliRunningUncompressedState::BROTLI_STATE_UNCOMPRESSED_WRITE;
1855        // s.partial_pos_rb += (size_t)s.ringbuffer_size;
1856        // No break, continue to next state by going aroudn the loop
1857      }
1858      BrotliRunningUncompressedState::BROTLI_STATE_UNCOMPRESSED_WRITE => {
1859        let (result, _) = WriteRingBuffer(&mut available_out,
1860                                          Some(&mut output),
1861                                          &mut output_offset,
1862                                          &mut total_out,
1863                                          false,
1864                                          &mut s);
1865        match result {
1866          BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS => {}
1867          _ => return result,
1868        }
1869        if s.ringbuffer_size == 1 << s.window_bits {
1870          s.max_distance = s.max_backward_distance;
1871        }
1872        s.substate_uncompressed = BrotliRunningUncompressedState::BROTLI_STATE_UNCOMPRESSED_NONE;
1873      }
1874    }
1875  }
1876}
1877
1878fn BrotliAllocateRingBuffer<AllocU8: alloc::Allocator<u8>,
1879                            AllocU32: alloc::Allocator<u32>,
1880                            AllocHC: alloc::Allocator<HuffmanCode>>
1881  (s: &mut BrotliState<AllocU8, AllocU32, AllocHC>,
1882   input: &[u8])
1883   -> bool {
1884  // We need the slack region for the following reasons:
1885  // - doing up to two 16-byte copies for fast backward copying (32 bytes,
1886  //   subsumed by the dictionary-word case below)
1887  // - inserting a transformed dictionary word past the end of the ring
1888  //   buffer: prefix + base word + suffix. The built-in transforms need only
1889  //   5 + 24 + 8 = 37, but a serialized shared dictionary may define
1890  //   transforms with full-length affixes, so a word starting on the last
1891  //   ring-buffer byte can write this far past it.
1892  const kRingBufferWriteAheadSlack: i32 =
1893    SHARED_BROTLI_MAX_TRANSFORM_AFFIX_LENGTH as i32           // 255-byte prefix
1894    + (SHARED_BROTLI_MAX_DICTIONARY_WORD_LENGTH as i32 + 1)   //  32: 31-byte word, rounded up
1895    + SHARED_BROTLI_MAX_TRANSFORM_AFFIX_LENGTH as i32;        // 255-byte suffix => 542
1896  // The C implementation hardcodes 542; fail the build if the two drift apart.
1897  const _RING_BUFFER_SLACK_MATCHES_C: [(); 542] = [(); kRingBufferWriteAheadSlack as usize];
1898  let mut is_last = s.is_last_metablock;
1899  s.ringbuffer_size = 1 << s.window_bits;
1900
1901  if (s.is_uncompressed != 0) {
1902    let next_block_header =
1903      bit_reader::BrotliPeekByte(&mut s.br, s.meta_block_remaining_len as u32, input);
1904    if (next_block_header != -1) &&
1905        // Peek succeeded
1906        ((next_block_header & 3) == 3) {
1907      // ISLAST and ISEMPTY
1908      is_last = 1;
1909    }
1910  }
1911  // We need at least 2 bytes of ring buffer size to get the last two
1912  // bytes for context from there
1913  if is_last != 0 && s.canny_ringbuffer_allocation {
1914    while (s.ringbuffer_size as isize >= (s.meta_block_remaining_len as isize + 16) * 2 && s.ringbuffer_size as isize > 32) {
1915      s.ringbuffer_size >>= 1;
1916    }
1917  }
1918  if s.ringbuffer_size > (1 << s.window_bits) {
1919    s.ringbuffer_size = (1 << s.window_bits);
1920  }
1921
1922  s.ringbuffer_mask = s.ringbuffer_size - 1;
1923  s.ringbuffer = s.alloc_u8
1924    .alloc_cell((s.ringbuffer_size as usize + kRingBufferWriteAheadSlack as usize +
1925                 kBrotliMaxDictionaryWordLength as usize));
1926  if (s.ringbuffer.slice().len() == 0) {
1927    return false;
1928  }
1929  fast_mut!((s.ringbuffer.slice_mut())[s.ringbuffer_size as usize - 1]) = 0;
1930  fast_mut!((s.ringbuffer.slice_mut())[s.ringbuffer_size as usize - 2]) = 0;
1931  true
1932}
1933
1934// Lazily builds compound_dictionary.block_map, a 256-entry table that maps
1935// address >> block_bits to the first chunk that might contain that address.
1936fn EnsureCompoundDictionaryInitialized<AllocU8: alloc::Allocator<u8>,
1937                                       AllocU32: alloc::Allocator<u32>,
1938                                       AllocHC: alloc::Allocator<HuffmanCode>>
1939  (s: &mut BrotliState<AllocU8, AllocU32, AllocHC>) {
1940  let addon = &mut s.compound_dictionary;
1941  // 256 = (1 << 8) slots in block map.
1942  let mut block_bits: u32 = 8;
1943  let maximal_address = addon.total_size as u32 - 1;
1944  if addon.block_bits != COMPOUND_DICTIONARY_BLOCK_MAP_UNINITIALIZED {
1945    return;
1946  }
1947  while (maximal_address >> block_bits) != 0 {
1948    block_bits += 1;
1949  }
1950  block_bits -= 8;
1951  addon.block_bits = block_bits;
1952  let mut cursor: u32 = 0;
1953  let mut index: usize = 0;
1954  while cursor <= maximal_address {
1955    // chunk_offsets[num_chunks] is a sentinel equal to maximal_address + 1.
1956    while fast!((addon.chunk_offsets)[index + 1]) < cursor {
1957      index += 1;
1958    }
1959    fast_mut!((addon.block_map)[(cursor >> block_bits) as usize]) = index as u8;
1960    match cursor.checked_add(1 << block_bits) {
1961      Some(next) => cursor = next,
1962      None => break,
1963    }
1964  }
1965  // Now if X is in the range [0..maximal_address] then
1966  // block_map[X >> block_bits] is in [0..num_chunks).
1967}
1968
1969// Prepares a copy of `length` bytes starting at compound dictionary address
1970// `address` (0 = first byte of the first chunk). Returns false if the copy
1971// would run off the end of the dictionary.
1972fn InitializeCompoundDictionaryCopy<AllocU8: alloc::Allocator<u8>,
1973                                    AllocU32: alloc::Allocator<u32>,
1974                                    AllocHC: alloc::Allocator<HuffmanCode>>
1975  (s: &mut BrotliState<AllocU8, AllocU32, AllocHC>,
1976   address: usize,
1977   length: usize)
1978   -> bool {
1979  EnsureCompoundDictionaryInitialized(s);
1980  let addon = &mut s.compound_dictionary;
1981  if length > addon.total_size - address {
1982    return false;
1983  }
1984  let mut index = fast!((addon.block_map)[address >> addon.block_bits]) as usize;
1985  // Several chunks might be mapped to the same block index.
1986  while address as u32 >= fast!((addon.chunk_offsets)[index + 1]) {
1987    index += 1;
1988  }
1989  // Update the recent distances cache.
1990  fast_mut!((s.dist_rb)[(s.dist_rb_idx & 3) as usize]) = s.distance_code;
1991  s.dist_rb_idx += 1;
1992  s.meta_block_remaining_len -= length as i32;
1993  addon.br_index = index;
1994  addon.br_offset = address - fast!((addon.chunk_offsets)[index]) as usize;
1995  addon.br_length = length;
1996  addon.br_copied = 0;
1997  true
1998}
1999
2000// Copies the prepared dictionary reference into the ring buffer at `pos`,
2001// stopping at the end of the ring buffer if necessary (the caller flushes
2002// and re-invokes). Returns the number of bytes copied.
2003fn CopyFromCompoundDictionary<AllocU8: alloc::Allocator<u8>,
2004                              AllocU32: alloc::Allocator<u32>,
2005                              AllocHC: alloc::Allocator<HuffmanCode>>
2006  (s: &mut BrotliState<AllocU8, AllocU32, AllocHC>,
2007   pos: i32)
2008   -> i32 {
2009  let ringbuffer_size = s.ringbuffer_size as usize;
2010  let mut pos = pos as usize;
2011  let orig_pos = pos;
2012  let addon = &mut s.compound_dictionary;
2013  while addon.br_length != addon.br_copied {
2014    let chunk = addon.chunks[addon.br_index].slice();
2015    let space = ringbuffer_size - pos;
2016    let rem_chunk_length = chunk.len() - addon.br_offset;
2017    let mut length = addon.br_length - addon.br_copied;
2018    if length > rem_chunk_length {
2019      length = rem_chunk_length;
2020    }
2021    if length > space {
2022      length = space;
2023    }
2024    fast_mut!((s.ringbuffer.slice_mut())[pos ; pos + length])
2025      .clone_from_slice(fast!((chunk)[addon.br_offset ; addon.br_offset + length]));
2026    pos += length;
2027    addon.br_offset += length;
2028    addon.br_copied += length;
2029    if length == rem_chunk_length {
2030      addon.br_index += 1;
2031      addon.br_offset = 0;
2032    }
2033    if pos == ringbuffer_size {
2034      break;
2035    }
2036  }
2037  (pos - orig_pos) as i32
2038}
2039
2040#[cfg(all(test, feature="std"))]
2041mod tests {
2042  use super::*;
2043
2044  fn ringbuffer_size(canny: bool) -> i32 {
2045    let mut state = BrotliState::new(::StandardAlloc::default(),
2046                                     ::StandardAlloc::default(),
2047                                     ::StandardAlloc::default());
2048    state.window_bits = 16;
2049    state.is_last_metablock = 1;
2050    state.canny_ringbuffer_allocation = canny;
2051    assert!(BrotliAllocateRingBuffer(&mut state, &[]));
2052    state.ringbuffer_size
2053  }
2054
2055  #[test]
2056  fn canny_ring_buffer() {
2057    assert_eq!(ringbuffer_size(true), 32);
2058    assert_eq!(ringbuffer_size(false), 1 << 16);
2059  }
2060
2061  #[test]
2062  fn take_output_returns_every_consumed_byte() {
2063    // The existing 10x10y stream, embedded so this regression needs no fixture.
2064    let input = [0x1b, 0x13, 0x00, 0x00, 0xa4, 0xb0, 0xb2, 0xea, 0x81, 0x47, 0x02, 0x8a];
2065    let expected = b"XXXXXXXXXXYYYYYYYYYY";
2066    let mut state = BrotliState::new(::StandardAlloc::default(),
2067                                     ::StandardAlloc::default(),
2068                                     ::StandardAlloc::default());
2069    let mut available_in = input.len();
2070    let mut input_offset = 0usize;
2071    let mut available_out = 0usize;
2072    let mut output_offset = 0usize;
2073    let mut total_out = 0usize;
2074    let result = BrotliDecompressStream(&mut available_in, &mut input_offset, &input,
2075                                        &mut available_out, &mut output_offset, &mut [],
2076                                        &mut total_out, &mut state);
2077    assert_eq!(result as i32, BrotliResult::NeedsMoreOutput as i32);
2078    assert_eq!(total_out, 0);
2079
2080    let mut consumed = 0usize;
2081    for &limit in &[1usize, 3, 7, 0] {
2082      assert!(BrotliDecoderHasMoreOutput(&state));
2083      let mut size = limit;
2084      {
2085        let output = BrotliDecoderTakeOutput(&mut state, &mut size);
2086        assert_eq!(size, if limit == 0 { expected.len() - consumed } else { limit });
2087        assert_eq!(output.len(), size);
2088        assert_eq!(output, &expected[consumed..consumed + size]);
2089      }
2090      consumed += size;
2091      assert_eq!(state.partial_pos_out, consumed as u64);
2092    }
2093    assert_eq!(consumed, expected.len());
2094    assert!(!BrotliDecoderHasMoreOutput(&state));
2095    for &limit in &[1usize, 0] {
2096      let mut size = limit;
2097      assert!(BrotliDecoderTakeOutput(&mut state, &mut size).is_empty());
2098      assert_eq!(size, 0);
2099    }
2100  }
2101
2102  fn assert_large_remaining_copy_is_clamped(meta_block_remaining_len: i32,
2103                                            pos: i32,
2104                                            expected_result: BrotliDecoderErrorCode) {
2105    let mut s = BrotliState::new(::StandardAlloc::default(),
2106                                 ::StandardAlloc::default(),
2107                                 ::StandardAlloc::default());
2108    s.ringbuffer_size = 16;
2109    s.window_bits = 5;
2110    s.ringbuffer = s.alloc_u8.alloc_cell(s.ringbuffer_size as usize);
2111    s.meta_block_remaining_len = meta_block_remaining_len;
2112    s.pos = pos;
2113    s.br.avail_in = 1u32 << 31;
2114
2115    let input = [0x5au8];
2116    let mut available_out = 0usize;
2117    let mut output = [0u8; 0];
2118    let mut output_offset = 0usize;
2119    let mut total_out = 0usize;
2120    let result = CopyUncompressedBlockToOutput(&mut available_out,
2121                                               &mut output,
2122                                               &mut output_offset,
2123                                               &mut total_out,
2124                                               &mut s,
2125                                               &input);
2126
2127    assert_eq!(result as i32, expected_result as i32);
2128    assert_eq!(s.br.avail_in, (1u32 << 31) - 1);
2129    assert_eq!(s.meta_block_remaining_len, meta_block_remaining_len - 1);
2130    assert_eq!(s.pos, pos + 1);
2131    assert_eq!(s.ringbuffer.slice()[pos as usize], input[0]);
2132  }
2133
2134  #[test]
2135  fn uncompressed_copy_clamps_unsigned_remaining_bytes() {
2136    assert_large_remaining_copy_is_clamped(
2137      1, 0, BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS);
2138    assert_large_remaining_copy_is_clamped(
2139      16, 15, BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT);
2140  }
2141
2142  #[test]
2143  fn stream_rejects_wrapping_output_range() {
2144    let mut state = BrotliState::new(::StandardAlloc::default(),
2145                                     ::StandardAlloc::default(),
2146                                     ::StandardAlloc::default());
2147    let input = [0x06u8];
2148    let mut output = [0u8; 1];
2149    let mut available_in = input.len();
2150    let mut input_offset = 0usize;
2151    let mut available_out = usize::MAX;
2152    let mut output_offset = 1usize;
2153    let mut total_out = 0usize;
2154
2155    let result = BrotliDecompressStream(&mut available_in,
2156                                        &mut input_offset,
2157                                        &input,
2158                                        &mut available_out,
2159                                        &mut output_offset,
2160                                        &mut output,
2161                                        &mut total_out,
2162                                        &mut state);
2163
2164    assert_eq!(result as i32, BrotliResult::ResultFailure as i32);
2165    assert_eq!(state.error_code as i32,
2166               BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_INVALID_ARGUMENTS as i32);
2167  }
2168
2169  #[test]
2170  fn stream_rejects_wrapping_input_range() {
2171    let mut state = BrotliState::new(::StandardAlloc::default(),
2172                                     ::StandardAlloc::default(),
2173                                     ::StandardAlloc::default());
2174    let input = [0x06u8];
2175    let mut output = [0u8; 1];
2176    // The end wraps to zero on 32-bit and is out of bounds on 64-bit.
2177    let mut available_in = u32::MAX as usize;
2178    let mut input_offset = 1usize;
2179    let mut available_out = output.len();
2180    let mut output_offset = 0usize;
2181    let mut total_out = 0usize;
2182
2183    let result = BrotliDecompressStream(&mut available_in,
2184                                        &mut input_offset,
2185                                        &input,
2186                                        &mut available_out,
2187                                        &mut output_offset,
2188                                        &mut output,
2189                                        &mut total_out,
2190                                        &mut state);
2191
2192    assert_eq!(result as i32, BrotliResult::ResultFailure as i32);
2193    assert_eq!(state.error_code as i32,
2194               BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_INVALID_ARGUMENTS as i32);
2195  }
2196
2197  #[test]
2198  fn format_distance_error_restores_huffman_tree_groups() {
2199    let mut state = BrotliState::new(::StandardAlloc::default(),
2200                                     ::StandardAlloc::default(),
2201                                     ::StandardAlloc::default());
2202    state.BrotliHuffmanTreeGroupInit(state::WhichTreeGroup::LITERAL, 1, 0, 1);
2203    state.BrotliHuffmanTreeGroupInit(state::WhichTreeGroup::INSERT_COPY, 1, 0, 2);
2204    state.BrotliHuffmanTreeGroupInit(state::WhichTreeGroup::DISTANCE, 1, 0, 3);
2205    let expected_code_lengths = [
2206      state.literal_hgroup.codes.slice().len(),
2207      state.insert_copy_hgroup.codes.slice().len(),
2208      state.distance_hgroup.codes.slice().len(),
2209    ];
2210
2211    state.state = BrotliRunningState::BROTLI_STATE_COMMAND_POST_DECODE_LITERALS;
2212    state.distance_code = 1;
2213    state.dist_rb_idx = 1;
2214    state.dist_rb[0] = i32::MAX;
2215    state.max_distance = 0;
2216    state.max_backward_distance = 0;
2217
2218    let result = ProcessCommandsInternal(true, &mut state, &[]);
2219
2220    assert_eq!(result as i32,
2221               BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_FORMAT_DISTANCE as i32);
2222    assert_eq!(state.literal_hgroup.codes.slice().len(), expected_code_lengths[0]);
2223    assert_eq!(state.insert_copy_hgroup.codes.slice().len(), expected_code_lengths[1]);
2224    assert_eq!(state.distance_hgroup.codes.slice().len(), expected_code_lengths[2]);
2225  }
2226}
2227
2228// Reads 1..256 2-bit context modes.
2229pub fn ReadContextModes<AllocU8: alloc::Allocator<u8>,
2230                        AllocU32: alloc::Allocator<u32>,
2231                        AllocHC: alloc::Allocator<HuffmanCode>>
2232  (s: &mut BrotliState<AllocU8, AllocU32, AllocHC>,
2233   input: &[u8])
2234   -> BrotliDecoderErrorCode {
2235
2236  let mut i: i32 = s.loop_counter;
2237
2238  for context_mode_iter in fast_mut!((s.context_modes.slice_mut())[i as usize ;
2239                                                       (s.block_type_length_state.num_block_types[0]
2240                                                        as usize)])
2241    .iter_mut() {
2242    let mut bits: u32 = 0;
2243    if (!bit_reader::BrotliSafeReadBits(&mut s.br, 2, &mut bits, input)) {
2244      mark_unlikely();
2245      s.loop_counter = i;
2246      return BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT;
2247    }
2248    *context_mode_iter = bits as u8;
2249    BROTLI_LOG_UINT!(i);
2250    i += 1;
2251  }
2252  BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS
2253}
2254
2255pub fn TakeDistanceFromRingBuffer<AllocU8: alloc::Allocator<u8>,
2256                                  AllocU32: alloc::Allocator<u32>,
2257                                  AllocHC: alloc::Allocator<HuffmanCode>>
2258  (s: &mut BrotliState<AllocU8, AllocU32, AllocHC>) {
2259  if (s.distance_code == 0) {
2260    s.dist_rb_idx -= 1;
2261    s.distance_code = fast!((s.dist_rb)[(s.dist_rb_idx & 3) as usize]);
2262    s.distance_context = 1;
2263  } else {
2264    let distance_code = s.distance_code << 1;
2265    // kDistanceShortCodeIndexOffset has 2-bit values from LSB:
2266    // 3, 2, 1, 0, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2
2267    const kDistanceShortCodeIndexOffset: u32 = 0xaaafff1b;
2268    // kDistanceShortCodeValueOffset has 2-bit values from LSB:
2269    // -0, 0,-0, 0,-1, 1,-2, 2,-3, 3,-1, 1,-2, 2,-3, 3
2270    const kDistanceShortCodeValueOffset: u32 = 0xfa5fa500;
2271    let mut v = (s.dist_rb_idx as i32 +
2272                 (kDistanceShortCodeIndexOffset as i32 >>
2273                  distance_code as i32)) as i32 & 0x3;
2274    s.distance_code = fast!((s.dist_rb)[v as usize]);
2275    v = (kDistanceShortCodeValueOffset >> distance_code) as i32 & 0x3;
2276    if ((distance_code & 0x3) != 0) {
2277      s.distance_code += v;
2278    } else {
2279      s.distance_code -= v;
2280      if (s.distance_code <= 0) {
2281        // A huge distance will cause a BROTLI_FAILURE() soon.
2282        // This is a little faster than failing here.
2283        s.distance_code = 0x7fffffff;
2284      }
2285    }
2286  }
2287}
2288
2289pub fn SafeReadBits(br: &mut bit_reader::BrotliBitReader,
2290                    n_bits: u32,
2291                    val: &mut u32,
2292                    input: &[u8])
2293                    -> bool {
2294  if (n_bits != 0) {
2295    bit_reader::BrotliSafeReadBits(br, n_bits, val, input)
2296  } else {
2297    *val = 0;
2298    true
2299  }
2300}
2301
2302// Precondition: s.distance_code < 0
2303#[inline(always)]
2304pub fn ReadDistanceInternal<AllocU8: alloc::Allocator<u8>,
2305                            AllocU32: alloc::Allocator<u32>,
2306                            AllocHC: alloc::Allocator<HuffmanCode>>
2307  (safe: bool,
2308   s: &mut BrotliState<AllocU8, AllocU32, AllocHC>,
2309   input: &[u8],
2310   distance_hgroup: &[&[HuffmanCode]; 256])
2311   -> bool {
2312  let mut distval: i32;
2313  let mut memento = bit_reader::BrotliBitReaderState::default();
2314  if (!safe) {
2315    s.distance_code = ReadSymbol(fast!((distance_hgroup)[s.dist_htree_index as usize]),
2316                                 &mut s.br,
2317                                 input) as i32;
2318  } else {
2319    let mut code: u32 = 0;
2320    memento = bit_reader::BrotliBitReaderSaveState(&s.br);
2321    if !SafeReadSymbol(fast!((distance_hgroup)[s.dist_htree_index as usize]),
2322                       &mut s.br,
2323                       &mut code,
2324                       input) {
2325      return false;
2326    }
2327    s.distance_code = code as i32;
2328  }
2329  // Convert the distance code to the actual distance by possibly
2330  // looking up past distances from the s.ringbuffer.
2331  s.distance_context = 0;
2332  if ((s.distance_code as u64 & 0xfffffffffffffff0) == 0) {
2333    TakeDistanceFromRingBuffer(s);
2334    fast_mut!((s.block_type_length_state.block_length)[2]) -= 1;
2335    return true;
2336  }
2337  distval = s.distance_code - s.num_direct_distance_codes as i32;
2338  if (distval >= 0) {
2339    let nbits: u32;
2340    let postfix: i32;
2341    let offset: i32;
2342    if (!safe && (s.distance_postfix_bits == 0)) {
2343      nbits = (distval as u32 >> 1) + 1;
2344      offset = ((2 + (distval & 1)) << nbits) - 4;
2345      s.distance_code = (s.num_direct_distance_codes as i64 + offset as i64 +
2346                        bit_reader::BrotliReadBits(&mut s.br, nbits, input) as i64) as i32;
2347    } else {
2348      // This branch also works well when s.distance_postfix_bits == 0
2349      let mut bits: u32 = 0;
2350      postfix = distval & s.distance_postfix_mask;
2351      distval >>= s.distance_postfix_bits;
2352      nbits = (distval as u32 >> 1) + 1;
2353      if (safe) {
2354        if (!SafeReadBits(&mut s.br, nbits, &mut bits, input)) {
2355          s.distance_code = -1; /* Restore precondition. */
2356          bit_reader::BrotliBitReaderRestoreState(&mut s.br, &memento);
2357          return false;
2358        }
2359      } else {
2360        bits = bit_reader::BrotliReadBits(&mut s.br, nbits, input);
2361      }
2362      offset = (((distval & 1).wrapping_add(2)) << nbits).wrapping_sub(4);
2363      s.distance_code = ((i64::from(offset) + i64::from(bits)) << s.distance_postfix_bits).wrapping_add(i64::from(postfix)).wrapping_add(i64::from(s.num_direct_distance_codes)) as i32;
2364    }
2365  }
2366  s.distance_code = s.distance_code.wrapping_sub(NUM_DISTANCE_SHORT_CODES as i32).wrapping_add(1);
2367  fast_mut!((s.block_type_length_state.block_length)[2]) -= 1;
2368  true
2369}
2370
2371#[inline(always)]
2372pub fn ReadCommandInternal<AllocU8: alloc::Allocator<u8>,
2373                           AllocU32: alloc::Allocator<u32>,
2374                           AllocHC: alloc::Allocator<HuffmanCode>>
2375  (safe: bool,
2376   s: &mut BrotliState<AllocU8, AllocU32, AllocHC>,
2377   insert_length: &mut i32,
2378   input: &[u8],
2379   insert_copy_hgroup: &[&[HuffmanCode]; 256])
2380   -> bool {
2381  let mut cmd_code: u32 = 0;
2382  let mut insert_len_extra: u32 = 0;
2383  let mut copy_length: u32 = 0;
2384  let v: prefix::CmdLutElement;
2385  let mut memento = bit_reader::BrotliBitReaderState::default();
2386  if (!safe) {
2387    cmd_code = ReadSymbol(fast!((insert_copy_hgroup)[s.htree_command_index as usize]),
2388                          &mut s.br,
2389                          input);
2390  } else {
2391    memento = bit_reader::BrotliBitReaderSaveState(&s.br);
2392    if (!SafeReadSymbol(fast!((insert_copy_hgroup)[s.htree_command_index as usize]),
2393                        &mut s.br,
2394                        &mut cmd_code,
2395                        input)) {
2396      return false;
2397    }
2398  }
2399  v = fast!((prefix::kCmdLut)[cmd_code as usize]);
2400  s.distance_code = v.distance_code as i32;
2401  s.distance_context = v.context as i32;
2402  s.dist_htree_index = fast_slice!((s.dist_context_map)[s.dist_context_map_slice_index
2403                                                  + s.distance_context as usize]);
2404  *insert_length = v.insert_len_offset as i32;
2405  if (!safe) {
2406    if v.insert_len_extra_bits != 0 {
2407      mark_unlikely();
2408      insert_len_extra =
2409        bit_reader::BrotliReadBits(&mut s.br, v.insert_len_extra_bits as u32, input);
2410    }
2411    copy_length = bit_reader::BrotliReadBits(&mut s.br, v.copy_len_extra_bits as u32, input);
2412  } else if (!SafeReadBits(&mut s.br,
2413                    v.insert_len_extra_bits as u32,
2414                    &mut insert_len_extra,
2415                    input)) ||
2416     (!SafeReadBits(&mut s.br,
2417                    v.copy_len_extra_bits as u32,
2418                    &mut copy_length,
2419                    input)) {
2420    bit_reader::BrotliBitReaderRestoreState(&mut s.br, &memento);
2421    return false;
2422  }
2423  s.copy_length = copy_length as i32 + v.copy_len_offset as i32;
2424  fast_mut!((s.block_type_length_state.block_length)[1]) -= 1;
2425  *insert_length += insert_len_extra as i32;
2426  true
2427}
2428
2429
2430#[inline(always)]
2431fn WarmupBitReader(safe: bool, br: &mut bit_reader::BrotliBitReader, input: &[u8]) -> bool {
2432  safe || bit_reader::BrotliWarmupBitReader(br, input)
2433}
2434
2435#[inline(always)]
2436fn CheckInputAmount(safe: bool, br: &bit_reader::BrotliBitReader, num: u32) -> bool {
2437  safe || bit_reader::BrotliCheckInputAmount(br, num)
2438}
2439
2440#[inline(always)]
2441fn memmove16(data: &mut [u8], u32off_dst: u32, u32off_src: u32) -> bool {
2442  let off_dst = u32off_dst as usize;
2443  let off_src = u32off_src as usize;
2444  // Always copies 16 bytes, so a caller copying fewer overshoots; the ring buffer
2445  // carries kRingBufferWriteAheadSlack bytes past ringbuffer_size to absorb it.
2446  // Subtraction, not `off + 16`, so nothing can wrap.
2447  let len = data.len();
2448  if len < 16 || core::cmp::max(off_dst, off_src) > len - 16 {
2449    return false;
2450  }
2451  let dst_end = off_dst + 16;
2452  let src_end = off_src + 16;
2453  // data[off_dst + 15] = data[off_src + 15];
2454  // data[off_dst + 14] = data[off_src + 14];
2455  // data[off_dst + 13] = data[off_src + 13];
2456  // data[off_dst + 12] = data[off_src + 12];
2457  //
2458  // data[off_dst + 11] = data[off_src + 11];
2459  // data[off_dst + 10] = data[off_src + 10];
2460  // data[off_dst + 9] = data[off_src + 9];
2461  // data[off_dst + 8] = data[off_src + 8];
2462  //
2463  // data[off_dst + 7] = data[off_src + 7];
2464  // data[off_dst + 6] = data[off_src + 6];
2465  // data[off_dst + 5] = data[off_src + 5];
2466  // data[off_dst + 4] = data[off_src + 4];
2467  //
2468  // data[off_dst + 3] = data[off_src + 3];
2469  // data[off_dst + 2] = data[off_src + 2];
2470  // data[off_dst + 1] = data[off_src + 1];
2471  //
2472  let mut local_array: [u8; 16] = fast_uninitialized!(16);
2473  local_array.clone_from_slice(&data[off_src..src_end]);
2474  data[off_dst..dst_end].clone_from_slice(&local_array);
2475  true
2476}
2477
2478#[inline(always)]
2479fn memcpy_within_slice(data: &mut [u8], off_dst: usize, off_src: usize, size: usize) -> bool {
2480  // Both ranges must fit and must not overlap: the `unsafe` build lowers this to
2481  // copy_nonoverlapping, and the safe build's split_at_mut would panic.
2482  // Subtraction, not `off + size`, so no caller offset can wrap past the checks.
2483  let len = data.len();
2484  let apart = if off_dst > off_src { off_dst - off_src } else { off_src - off_dst };
2485  if size > len || off_dst > len - size || off_src > len - size || apart < size {
2486    return false;
2487  }
2488
2489  #[cfg(not(feature="unsafe"))]
2490  {
2491    if off_dst > off_src {
2492      let (src, dst) = data.split_at_mut(off_dst);
2493      let src_slice = fast!((src)[off_src ; off_src + size]);
2494      fast_mut!((dst)[0;size]).clone_from_slice(src_slice);
2495    } else {
2496      let (dst, src) = data.split_at_mut(off_src);
2497      let src_slice = fast!((src)[0;size]);
2498      fast_mut!((dst)[off_dst;off_dst + size]).clone_from_slice(src_slice);
2499    }
2500  }
2501
2502  #[cfg(feature="unsafe")]
2503  unsafe {
2504    let ptr = data.as_mut_ptr();
2505    let dst = ptr.add(off_dst);
2506    let src = ptr.add(off_src);
2507    core::ptr::copy_nonoverlapping(src, dst, size);
2508  }
2509  true
2510}
2511
2512pub fn BrotliDecoderHasMoreOutput<AllocU8: alloc::Allocator<u8>,
2513                           AllocU32: alloc::Allocator<u32>,
2514                           AllocHC: alloc::Allocator<HuffmanCode>>
2515  (s: &BrotliState<AllocU8, AllocU32, AllocHC>) -> bool {
2516  /* After unrecoverable error remaining output is considered nonsensical. */
2517  if is_fatal(s.error_code) {
2518    return false;
2519  }
2520  s.ringbuffer.len() != 0 && CheckRingBufferConsistency(s) && UnwrittenBytes(s, false) != 0
2521}
2522pub fn BrotliDecoderTakeOutput<'a,
2523                               AllocU8: alloc::Allocator<u8>,
2524                               AllocU32: alloc::Allocator<u32>,
2525                               AllocHC: alloc::Allocator<HuffmanCode>>(
2526  s: &'a mut BrotliState<AllocU8, AllocU32, AllocHC>,
2527  size: &mut usize,
2528) -> &'a [u8] {
2529  let one:usize = 1;
2530  let mut available_out = if *size != 0 { *size } else { one << 24 };
2531  let requested_out = available_out;
2532  if (s.ringbuffer.len() == 0) || is_fatal(s.error_code) {
2533    *size = 0;
2534    return &[];
2535  }
2536  if !WrapRingBuffer(s) {
2537    s.error_code = BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_UNREACHABLE;
2538    *size = 0;
2539    return &[];
2540  }
2541  let mut ign = 0usize;
2542  let mut ign2 = 0usize;
2543  let (status, result) = WriteRingBuffer(&mut available_out, None, &mut ign,&mut ign2, true, s);
2544  // Either WriteRingBuffer returns those "success" codes...
2545  match status {
2546    BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS |  BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_OUTPUT => {
2547      *size = requested_out - available_out;
2548    },
2549    _ => {
2550      // ... or stream is broken. Normally this should be caught by
2551      //   BrotliDecoderDecompressStream, this is just a safeguard.
2552      if is_fatal(status) {
2553        // SaveErrorCode!(s, status); //borrow checker doesn't like this
2554        // but since it's a safeguard--ignore
2555      }
2556      *size = 0;
2557      return &[];
2558    }
2559  }
2560  return result;
2561}
2562
2563#[cfg(feature="ffi-api")]
2564pub fn BrotliDecoderIsUsed<AllocU8: alloc::Allocator<u8>,
2565                           AllocU32: alloc::Allocator<u32>,
2566                           AllocHC: alloc::Allocator<HuffmanCode>>(
2567  s: &BrotliState<AllocU8, AllocU32, AllocHC>) -> bool {
2568  !matches!(s.state, BrotliRunningState::BROTLI_STATE_UNINITED)
2569    || bit_reader::BrotliGetAvailableBits(&s.br) != 0
2570}
2571
2572pub fn BrotliDecoderIsFinished<AllocU8: alloc::Allocator<u8>,
2573                               AllocU32: alloc::Allocator<u32>,
2574                               AllocHC: alloc::Allocator<HuffmanCode>>(
2575  s: &BrotliState<AllocU8, AllocU32, AllocHC>) -> bool {
2576  if let BrotliRunningState::BROTLI_STATE_DONE = s.state {
2577    !BrotliDecoderHasMoreOutput(s)
2578  } else {
2579    false
2580  }
2581}
2582
2583pub fn BrotliDecoderGetErrorCode<AllocU8: alloc::Allocator<u8>,
2584                               AllocU32: alloc::Allocator<u32>,
2585                               AllocHC: alloc::Allocator<HuffmanCode>>(
2586  s: &BrotliState<AllocU8, AllocU32, AllocHC>) -> BrotliDecoderErrorCode {
2587  s.error_code
2588}
2589
2590#[inline(always)]
2591fn ProcessCommandsInternal<AllocU8: alloc::Allocator<u8>,
2592                           AllocU32: alloc::Allocator<u32>,
2593                           AllocHC: alloc::Allocator<HuffmanCode>>
2594  (safe: bool,
2595   s: &mut BrotliState<AllocU8, AllocU32, AllocHC>,
2596   input: &[u8])
2597   -> BrotliDecoderErrorCode {
2598  if (!CheckInputAmount(safe, &s.br, 28)) || (!WarmupBitReader(safe, &mut s.br, input)) {
2599    mark_unlikely();
2600    return BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT;
2601  }
2602  let mut pos = s.pos;
2603  let mut i: i32 = s.loop_counter; // important that this is signed
2604  let mut result = BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS;
2605  let compound_dictionary_size = s.compound_dictionary.total_size as u32;
2606  let mut saved_literal_hgroup =
2607    core::mem::replace(&mut s.literal_hgroup,
2608                       HuffmanTreeGroup::<AllocU32, AllocHC>::default());
2609  let mut saved_distance_hgroup =
2610    core::mem::replace(&mut s.distance_hgroup,
2611                       HuffmanTreeGroup::<AllocU32, AllocHC>::default());
2612  let mut saved_insert_copy_hgroup =
2613    core::mem::replace(&mut s.insert_copy_hgroup,
2614                       HuffmanTreeGroup::<AllocU32, AllocHC>::default());
2615  {
2616
2617    let literal_hgroup = saved_literal_hgroup.build_hgroup_cache();
2618    let distance_hgroup = saved_distance_hgroup.build_hgroup_cache();
2619    let insert_copy_hgroup = saved_insert_copy_hgroup.build_hgroup_cache();
2620
2621    loop {
2622      match s.state {
2623        BrotliRunningState::BROTLI_STATE_COMMAND_BEGIN => {
2624          if (!CheckInputAmount(safe, &s.br, 28)) {
2625            // 156 bits + 7 bytes
2626            mark_unlikely();
2627            result = BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT;
2628            break; // return
2629          }
2630          if (fast_mut!((s.block_type_length_state.block_length)[1]) == 0) {
2631            mark_unlikely();
2632            if !DecodeCommandBlockSwitchInternal(safe, s, input) {
2633              result = BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT;
2634              break; // return
2635            }
2636            s.state = BrotliRunningState::BROTLI_STATE_COMMAND_BEGIN;
2637            continue; // goto CommandBegin;
2638          }
2639          // Read the insert/copy length in the command
2640          if (!ReadCommandInternal(safe, s, &mut i, input, &insert_copy_hgroup)) && safe {
2641            result = BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT;
2642            break; // return
2643          }
2644          BROTLI_LOG!("[ProcessCommandsInternal] pos = %d insert = %d copy = %d distance = %d\n",
2645              pos, i, s.copy_length, s.distance_code);
2646          if (i == 0) {
2647            s.state = BrotliRunningState::BROTLI_STATE_COMMAND_POST_DECODE_LITERALS;
2648            continue; // goto CommandPostDecodeLiterals;
2649          }
2650          s.meta_block_remaining_len -= i;
2651          s.state = BrotliRunningState::BROTLI_STATE_COMMAND_INNER;
2652        }
2653        BrotliRunningState::BROTLI_STATE_COMMAND_INNER => {
2654          // Read the literals in the command
2655          if (s.trivial_literal_context != 0) {
2656            let mut bits: u32 = 0;
2657            let mut value: u32 = 0;
2658            let mut literal_htree = &fast!((literal_hgroup)[s.literal_htree_index as usize]);
2659            PreloadSymbol(safe, literal_htree, &mut s.br, &mut bits, &mut value, input);
2660            let mut inner_return: bool = false;
2661            let mut inner_continue: bool = false;
2662            loop {
2663              if (!CheckInputAmount(safe, &s.br, 28)) {
2664                // 162 bits + 7 bytes
2665                result = BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT;
2666                inner_return = true;
2667                break;
2668              }
2669              if (fast!((s.block_type_length_state.block_length)[0]) == 0) {
2670                mark_unlikely();
2671                if (!DecodeLiteralBlockSwitchInternal(safe, s, input)) && safe {
2672                  result = BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT;
2673                  inner_return = true;
2674                  break;
2675                }
2676                literal_htree = fast_ref!((literal_hgroup)[s.literal_htree_index as usize]);
2677                PreloadSymbol(safe, literal_htree, &mut s.br, &mut bits, &mut value, input);
2678                if (s.trivial_literal_context == 0) {
2679                  s.state = BrotliRunningState::BROTLI_STATE_COMMAND_INNER;
2680                  inner_continue = true;
2681                  break; // goto StateCommandInner
2682                }
2683              }
2684              if (!safe) {
2685                fast_mut!((s.ringbuffer.slice_mut())[pos as usize]) =
2686                  ReadPreloadedSymbol(literal_htree, &mut s.br, &mut bits, &mut value, input) as u8;
2687              } else {
2688                let mut literal: u32 = 0;
2689                if (!SafeReadSymbol(literal_htree, &mut s.br, &mut literal, input)) {
2690                  result = BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT;
2691                  inner_return = true;
2692                  break;
2693                }
2694                fast_mut!((s.ringbuffer.slice_mut())[pos as usize]) = literal as u8;
2695              }
2696              if (s.block_type_length_state.block_length)[0] == 0 {
2697                  mark_unlikely();
2698                  result = BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS;
2699                  inner_return = true;
2700                  break;
2701              }
2702              fast_mut!((s.block_type_length_state.block_length)[0]) -= 1;
2703              BROTLI_LOG_UINT!(s.literal_htree_index);
2704              BROTLI_LOG_ARRAY_INDEX!(s.ringbuffer.slice(), pos);
2705              pos += 1;
2706              if (pos == s.ringbuffer_size) {
2707                mark_unlikely();
2708                s.state = BrotliRunningState::BROTLI_STATE_COMMAND_INNER_WRITE;
2709                i -= 1;
2710                inner_return = true;
2711                break;
2712              }
2713              i -= 1;
2714              if i == 0 {
2715                break;
2716              }
2717            }
2718            if inner_return {
2719              break; // return
2720            }
2721            if inner_continue {
2722              mark_unlikely();
2723              continue;
2724            }
2725          } else {
2726            let mut p1 = fast_slice!((s.ringbuffer)[((pos - 1) & s.ringbuffer_mask) as usize]);
2727            let mut p2 = fast_slice!((s.ringbuffer)[((pos - 2) & s.ringbuffer_mask) as usize]);
2728            let mut inner_return: bool = false;
2729            let mut inner_continue: bool = false;
2730            loop {
2731              if (!CheckInputAmount(safe, &s.br, 28)) {
2732                // 162 bits + 7 bytes
2733                s.state = BrotliRunningState::BROTLI_STATE_COMMAND_INNER;
2734                result = BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT;
2735                inner_return = true;
2736                break;
2737              }
2738              if (fast!((s.block_type_length_state.block_length)[0]) == 0) {
2739                mark_unlikely();
2740                if (!DecodeLiteralBlockSwitchInternal(safe, s, input)) && safe {
2741                  result = BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT;
2742                  inner_return = true;
2743                  break;
2744                }
2745                if s.trivial_literal_context != 0 {
2746                  s.state = BrotliRunningState::BROTLI_STATE_COMMAND_INNER;
2747                  inner_continue = true;
2748                  break;
2749                }
2750              }
2751              let context = s.context_lookup[p1 as usize] | s.context_lookup[p2 as usize |256];
2752              BROTLI_LOG_UINT!(p1);
2753              BROTLI_LOG_UINT!(p2);
2754              BROTLI_LOG_UINT!(context);
2755              let hc: &[HuffmanCode];
2756              {
2757                let i = fast_slice!((s.context_map)[s.context_map_slice_index + context as usize]);
2758                hc = fast!((literal_hgroup)[i as usize]);
2759              }
2760              p2 = p1;
2761              if (!safe) {
2762                p1 = ReadSymbol(hc, &mut s.br, input) as u8;
2763              } else {
2764                let mut literal: u32 = 0;
2765                if (!SafeReadSymbol(hc, &mut s.br, &mut literal, input)) {
2766                  result = BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT;
2767                  inner_return = true;
2768                  break;
2769                }
2770                p1 = literal as u8;
2771              }
2772              fast_slice_mut!((s.ringbuffer)[pos as usize]) = p1;
2773              if (s.block_type_length_state.block_length)[0] == 0 {
2774                  result = BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS;
2775                  inner_return = true;
2776                  break;
2777              }
2778              fast_mut!((s.block_type_length_state.block_length)[0]) -= 1;
2779              BROTLI_LOG_UINT!(s.context_map.slice()[s.context_map_slice_index as usize +
2780                                                     context as usize]);
2781              BROTLI_LOG_ARRAY_INDEX!(s.ringbuffer.slice(), pos & s.ringbuffer_mask);
2782              pos += 1;
2783              if (pos == s.ringbuffer_size) {
2784                mark_unlikely();
2785                s.state = BrotliRunningState::BROTLI_STATE_COMMAND_INNER_WRITE;
2786                i -= 1;
2787                inner_return = true;
2788                break;
2789              }
2790              i -= 1;
2791              if i == 0 {
2792                break;
2793              }
2794            }
2795            if inner_return {
2796              break; // return
2797            }
2798            if inner_continue {
2799              mark_unlikely();
2800              continue;
2801            }
2802          }
2803          if (s.meta_block_remaining_len <= 0) {
2804            mark_unlikely();
2805            s.state = BrotliRunningState::BROTLI_STATE_METABLOCK_DONE;
2806            break; // return
2807          }
2808          s.state = BrotliRunningState::BROTLI_STATE_COMMAND_POST_DECODE_LITERALS;
2809        }
2810        BrotliRunningState::BROTLI_STATE_COMMAND_POST_DECODE_LITERALS => {
2811          if s.distance_code >= 0 {
2812            let not_distance_code = if s.distance_code != 0 { 0 } else { 1 };
2813            s.distance_context = not_distance_code;
2814            s.dist_rb_idx -= 1;
2815            s.distance_code = fast!((s.dist_rb)[(s.dist_rb_idx & 3) as usize]);
2816            // goto postReadDistance
2817          } else {
2818            if fast!((s.block_type_length_state.block_length)[2]) == 0 {
2819              mark_unlikely();
2820              if (!DecodeDistanceBlockSwitchInternal(safe, s, input)) && safe {
2821                result = BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT;
2822                break; // return
2823              }
2824            }
2825            if (!ReadDistanceInternal(safe, s, input, &distance_hgroup)) && safe {
2826              result = BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT;
2827              break; // return
2828            }
2829          }
2830          // postReadDistance:
2831          BROTLI_LOG!("[ProcessCommandsInternal] pos = %d distance = %d\n",
2832                      pos, s.distance_code);
2833
2834          if (s.max_distance != s.max_backward_distance) {
2835            s.max_distance = if pos < s.max_backward_distance {
2836              pos
2837            } else {
2838              s.max_backward_distance
2839            };
2840          }
2841          i = s.copy_length;
2842          // Apply copy of LZ77 back-reference, or static dictionary reference if
2843          // the distance is larger than the max LZ77 distance
2844          if (s.distance_code > s.max_distance) {
2845            if s.distance_code > kBrotliMaxAllowedDistance as i32 {
2846              result = BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_FORMAT_DISTANCE;
2847              break;
2848            }
2849            // Distances in (max_distance, max_distance + compound_dictionary_size]
2850            // address the attached compound dictionary, furthest byte first.
2851            if (s.distance_code - s.max_distance) as u32 <= compound_dictionary_size {
2852              let address = compound_dictionary_size -
2853                            (s.distance_code - s.max_distance) as u32;
2854              if !InitializeCompoundDictionaryCopy(s, address as usize, i as usize) {
2855                result = BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_COMPOUND_DICTIONARY;
2856                break; // return
2857              }
2858              pos += CopyFromCompoundDictionary(s, pos);
2859              if pos >= s.ringbuffer_size {
2860                s.state = BrotliRunningState::BROTLI_STATE_COMMAND_POST_WRITE_1;
2861                break; // return
2862              }
2863            } else if s.dictionary.is_custom() &&
2864                i >= SHARED_BROTLI_MIN_DICTIONARY_WORD_LENGTH as i32 &&
2865                i <= SHARED_BROTLI_MAX_DICTIONARY_WORD_LENGTH as i32 {
2866              // Generalized lookup with the word/transform lists of an
2867              // attached serialized shared dictionary; mirrors the
2868              // corresponding branch in c/dec/decode.c.
2869              let dict_id = if s.dictionary.context_based {
2870                let p1 = fast_slice!((s.ringbuffer)[((pos - 1) & s.ringbuffer_mask) as usize]);
2871                let p2 = fast_slice!((s.ringbuffer)[((pos - 2) & s.ringbuffer_mask) as usize]);
2872                let context = (s.context_lookup[p1 as usize] |
2873                               s.context_lookup[p2 as usize | 256]) as usize;
2874                s.dictionary.context_map[context]
2875              } else {
2876                0
2877              };
2878              let address = s.distance_code - s.max_distance - 1 -
2879                            compound_dictionary_size as i32;
2880              // Compensate double distance-ring-buffer roll.
2881              s.dist_rb_idx += s.distance_context;
2882              let lookup = match s.dictionary.lookup(dict_id, i, address) {
2883                Ok(lookup) => lookup,
2884                Err(why) => {
2885                  BROTLI_LOG!(
2886                    "Invalid backward reference. pos: %d distance: %d len: %d bytes left: %d\n",
2887                    pos, s.distance_code, i, s.meta_block_remaining_len);
2888                  result = match why {
2889                    DictionaryLookupError::LengthNotEncodable =>
2890                      BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_FORMAT_DICTIONARY,
2891                    DictionaryLookupError::AddressOutOfRange =>
2892                      BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_FORMAT_TRANSFORM,
2893                  };
2894                  break; // return
2895                },
2896              };
2897              {
2898                let mut len = i;
2899                let word = lookup.words.word(len, lookup.word_idx);
2900                if lookup.transform_idx == lookup.transforms.cutoff_identity() {
2901                  fast_slice_mut!((s.ringbuffer)[pos as usize ; ((pos + len) as usize)])
2902                    .clone_from_slice(word);
2903                } else {
2904                  len = lookup.transforms.apply(
2905                            fast_slice_mut!((s.ringbuffer)[pos as usize;]),
2906                            word,
2907                            len,
2908                            lookup.transform_idx);
2909                  if len == 0 && s.distance_code <= 120 {
2910                    result = BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_FORMAT_TRANSFORM;
2911                    break; // return
2912                  }
2913                }
2914                pos += len;
2915                s.meta_block_remaining_len -= len;
2916                if (pos >= s.ringbuffer_size) {
2917                  s.state = BrotliRunningState::BROTLI_STATE_COMMAND_POST_WRITE_1;
2918                  break; // return return
2919                }
2920              }
2921            } else if (i >= kBrotliMinDictionaryWordLength as i32 &&
2922                i <= kBrotliMaxDictionaryWordLength as i32) {
2923              let mut offset = fast!((kBrotliDictionaryOffsetsByLength)[i as usize]) as i32;
2924              let word_id = s.distance_code - s.max_distance - 1 -
2925                            compound_dictionary_size as i32;
2926              let shift = fast!((kBrotliDictionarySizeBitsByLength)[i as usize]);
2927              let mask = bit_reader::BitMask(shift as u32) as i32;
2928              let word_idx = word_id & mask;
2929              let transform_idx = word_id >> shift;
2930              s.dist_rb_idx += s.distance_context;
2931              offset += word_idx * i;
2932              if (transform_idx < kNumTransforms) {
2933                let mut len = i;
2934                let word = fast!((kBrotliDictionary)[offset as usize ; (offset + len) as usize]);
2935                if (transform_idx == 0) {
2936                  fast_slice_mut!((s.ringbuffer)[pos as usize ; ((pos + len) as usize)])
2937                    .clone_from_slice(word);
2938                } else {
2939                  len = TransformDictionaryWord(fast_slice_mut!((s.ringbuffer)[pos as usize;]),
2940                                                word,
2941                                                len,
2942                                                transform_idx);
2943                }
2944                pos += len;
2945                s.meta_block_remaining_len -= len;
2946                if (pos >= s.ringbuffer_size) {
2947                  // s.partial_pos_rb += (size_t)s.ringbuffer_size;
2948                  s.state = BrotliRunningState::BROTLI_STATE_COMMAND_POST_WRITE_1;
2949                  break; // return return
2950                }
2951              } else {
2952                BROTLI_LOG!(
2953                  "Invalid backward reference. pos: %d distance: %d len: %d bytes left: %d\n",
2954                  pos, s.distance_code, i,
2955                  s.meta_block_remaining_len);
2956                result = BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_FORMAT_TRANSFORM;
2957                break; // return
2958              }
2959            } else {
2960              BROTLI_LOG!(
2961                "Invalid backward reference. pos:%d distance:%d len:%d bytes left:%d\n",
2962                pos, s.distance_code, i, s.meta_block_remaining_len);
2963              result = BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_FORMAT_DICTIONARY;
2964              break; // return
2965            }
2966          } else {
2967            // update the recent distances cache
2968            fast_mut!((s.dist_rb)[(s.dist_rb_idx & 3) as usize]) = s.distance_code;
2969            s.dist_rb_idx += 1;
2970            s.meta_block_remaining_len -= i;
2971            // There is 128+ bytes of slack in the ringbuffer allocation.
2972            // Also, we have 16 short codes, that make these 16 bytes irrelevant
2973            // in the ringbuffer. Let's copy over them as a first guess.
2974            //
2975            let src_start = ((pos - s.distance_code) & s.ringbuffer_mask) as u32;
2976            let dst_start = pos as u32;
2977            let dst_end = pos as u32 + i as u32;
2978            let src_end = src_start + i as u32;
2979            if !memmove16(&mut s.ringbuffer.slice_mut(), dst_start, src_start) {
2980              result = BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_FORMAT_DISTANCE;
2981              break;
2982            }
2983            // Now check if the copy extends over the ringbuffer end,
2984            // or if the copy overlaps with itself, if yes, do wrap-copy.
2985            if (src_end > pos as u32 && dst_end > src_start) {
2986              s.state = BrotliRunningState::BROTLI_STATE_COMMAND_POST_WRAP_COPY;
2987              continue; //goto CommandPostWrapCopy;
2988            }
2989            if (dst_end >= s.ringbuffer_size as u32 || src_end >= s.ringbuffer_size as u32) {
2990              s.state = BrotliRunningState::BROTLI_STATE_COMMAND_POST_WRAP_COPY;
2991              continue; //goto CommandPostWrapCopy;
2992            }
2993            pos += i;
2994            if (i > 16) {
2995              if (i > 32) {
2996                if !memcpy_within_slice(s.ringbuffer.slice_mut(),
2997                                        dst_start as usize + 16,
2998                                        src_start as usize + 16,
2999                                        (i - 16) as usize) {
3000                  result = BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_FORMAT_DISTANCE;
3001                  break;
3002                }
3003              } else {
3004                // This branch covers about 45% cases.
3005                // Fixed size short copy allows more compiler optimizations.
3006                if !memmove16(&mut s.ringbuffer.slice_mut(),
3007                              dst_start + 16,
3008                              src_start + 16) {
3009                  result = BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_FORMAT_DISTANCE;
3010                  break;
3011                }
3012              }
3013            }
3014          }
3015          if (s.meta_block_remaining_len <= 0) {
3016            // Next metablock, if any
3017            s.state = BrotliRunningState::BROTLI_STATE_METABLOCK_DONE;
3018            break; // return
3019          } else {
3020            s.state = BrotliRunningState::BROTLI_STATE_COMMAND_BEGIN;
3021            continue; // goto CommandBegin
3022          }
3023        }
3024        BrotliRunningState::BROTLI_STATE_COMMAND_POST_WRAP_COPY => {
3025          let mut wrap_guard = s.ringbuffer_size - pos;
3026          let mut inner_return: bool = false;
3027          while i > 0 {
3028            i -= 1;
3029            fast_slice_mut!((s.ringbuffer)[pos as usize]) =
3030              fast_slice!((s.ringbuffer)[((pos - s.distance_code) & s.ringbuffer_mask) as usize]);
3031            pos += 1;
3032            wrap_guard -= 1;
3033            if (wrap_guard == 0) {
3034              mark_unlikely();
3035              // s.partial_pos_rb += (size_t)s.ringbuffer_size;
3036              s.state = BrotliRunningState::BROTLI_STATE_COMMAND_POST_WRITE_2;
3037              inner_return = true;
3038              break; //return
3039            }
3040          }
3041          if inner_return {
3042            mark_unlikely();
3043            break;
3044          }
3045          i -= 1;
3046          if (s.meta_block_remaining_len <= 0) {
3047            // Next metablock, if any
3048            s.state = BrotliRunningState::BROTLI_STATE_METABLOCK_DONE;
3049            break; // return
3050          } else {
3051            s.state = BrotliRunningState::BROTLI_STATE_COMMAND_BEGIN;
3052            continue;
3053          }
3054        }
3055        _ => {
3056          result = BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_UNREACHABLE;
3057          break; // return
3058        }
3059      }
3060    }
3061  }
3062  s.pos = pos;
3063  s.loop_counter = i;
3064
3065  let _ = core::mem::replace(&mut s.literal_hgroup,
3066                     core::mem::replace(&mut saved_literal_hgroup,
3067                                        HuffmanTreeGroup::<AllocU32, AllocHC>::default()));
3068
3069  let _ = core::mem::replace(&mut s.distance_hgroup,
3070                     core::mem::replace(&mut saved_distance_hgroup,
3071                                        HuffmanTreeGroup::<AllocU32, AllocHC>::default()));
3072
3073  let _ = core::mem::replace(&mut s.insert_copy_hgroup,
3074                     core::mem::replace(&mut saved_insert_copy_hgroup,
3075                                        HuffmanTreeGroup::<AllocU32, AllocHC>::default()));
3076
3077  result
3078}
3079
3080fn ProcessCommands<AllocU8: alloc::Allocator<u8>,
3081                   AllocU32: alloc::Allocator<u32>,
3082                   AllocHC: alloc::Allocator<HuffmanCode>>
3083  (s: &mut BrotliState<AllocU8, AllocU32, AllocHC>,
3084   input: &[u8])
3085   -> BrotliDecoderErrorCode {
3086  ProcessCommandsInternal(false, s, input)
3087}
3088
3089fn SafeProcessCommands<AllocU8: alloc::Allocator<u8>,
3090                       AllocU32: alloc::Allocator<u32>,
3091                       AllocHC: alloc::Allocator<HuffmanCode>>
3092  (s: &mut BrotliState<AllocU8, AllocU32, AllocHC>,
3093   input: &[u8])
3094   -> BrotliDecoderErrorCode {
3095  ProcessCommandsInternal(true, s, input)
3096}
3097
3098/* Returns the maximum number of distance symbols which can only represent
3099   distances not exceeding BROTLI_MAX_ALLOWED_DISTANCE. */
3100pub fn BrotliMaxDistanceSymbol(ndirect: u32, npostfix: u32) -> u32{
3101  let bound:[u32;kBrotliMaxPostfix + 1] = [0, 4, 12, 28];
3102  let diff:[u32;kBrotliMaxPostfix + 1] = [73, 126, 228, 424];
3103  let postfix = 1 << npostfix;
3104  if (ndirect < bound[npostfix as usize ]) {
3105    return ndirect + diff[npostfix as usize] + postfix;
3106  } else if (ndirect > bound[npostfix as usize] + postfix) {
3107    return ndirect + diff[npostfix as usize];
3108  } else {
3109    return bound[npostfix as usize] + diff[npostfix as usize] + postfix;
3110  }
3111}
3112
3113pub fn BrotliDecompressStream<AllocU8: alloc::Allocator<u8>,
3114                              AllocU32: alloc::Allocator<u32>,
3115                              AllocHC: alloc::Allocator<HuffmanCode>>
3116  (available_in: &mut usize,
3117   input_offset: &mut usize,
3118   xinput: &[u8],
3119   mut available_out: &mut usize,
3120   mut output_offset: &mut usize,
3121   mut output: &mut [u8],
3122   mut total_out: &mut usize,
3123   mut s: &mut BrotliState<AllocU8, AllocU32, AllocHC>)
3124   -> BrotliResult {
3125
3126  let mut result = BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS;
3127
3128  let mut saved_buffer: [u8; 8] = s.buffer;
3129  let mut local_input: &[u8];
3130  if is_fatal(s.error_code) {
3131    return BrotliResult::ResultFailure;
3132  }
3133  if !bit_reader::is_valid_input_range(*input_offset, *available_in, xinput.len()) {
3134    return SaveErrorCode!(s, BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_INVALID_ARGUMENTS);
3135  }
3136  match output_offset.checked_add(*available_out) {
3137    Some(end) if end <= output.len() => {}
3138    _ => return SaveErrorCode!(s, BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_INVALID_ARGUMENTS),
3139  }
3140  if s.buffer_length as usize > s.buffer.len() {
3141    return SaveErrorCode!(s, BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_UNREACHABLE);
3142  }
3143  if s.buffer_length == 0 {
3144    local_input = xinput;
3145    s.br.avail_in = *available_in as u32;
3146    s.br.next_in = *input_offset as u32;
3147  } else {
3148    result = BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT;
3149    let copy_len = core::cmp::min(saved_buffer.len() - s.buffer_length as usize, *available_in);
3150    if copy_len > 0 {
3151      fast_mut!((saved_buffer)[s.buffer_length as usize ; (s.buffer_length as usize + copy_len)])
3152        .clone_from_slice(fast!((xinput)[*input_offset ; copy_len + *input_offset]));
3153      fast_mut!((s.buffer)[s.buffer_length as usize ; (s.buffer_length as usize + copy_len)])
3154        .clone_from_slice(fast!((xinput)[*input_offset ; copy_len + *input_offset]));
3155    }
3156    local_input = &saved_buffer[..];
3157    s.br.next_in = 0;
3158  }
3159  loop {
3160    match result {
3161      BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS => {}
3162      _ => {
3163        match result {
3164          BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT => {
3165            if s.ringbuffer.slice().len() != 0 {
3166              let (intermediate_result, _) = WriteRingBuffer(available_out,
3167                                                             Some(&mut output),
3168                                                             &mut output_offset,
3169                                                             &mut total_out,
3170                                                             true,
3171                                                             &mut s);
3172              if is_fatal(intermediate_result) {
3173                result = intermediate_result;
3174                break;
3175              }
3176            }
3177            if s.buffer_length != 0 {
3178              // Used with internal buffer.
3179              if s.br.avail_in == 0 {
3180                // Successfully finished read transaction.
3181                // Accamulator contains less than 8 bits, because internal buffer
3182                // is expanded byte-by-byte until it is enough to complete read.
3183                s.buffer_length = 0;
3184                // Switch to input stream and restart.
3185                result = BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS;
3186                local_input = xinput;
3187                s.br.avail_in = *available_in as u32;
3188                s.br.next_in = *input_offset as u32;
3189                continue;
3190              } else if *available_in != 0 {
3191                // Not enough data in buffer, but can take one more byte from
3192                // input stream.
3193                result = BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS;
3194                let new_byte = fast!((xinput)[*input_offset]);
3195                let buffer_length = s.buffer_length as usize;
3196                // This byte was copied into saved_buffer at function entry.
3197                if saved_buffer.get(buffer_length) != Some(&new_byte) {
3198                  result = BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_UNREACHABLE;
3199                  break;
3200                }
3201                s.buffer[buffer_length] = new_byte;
3202                s.buffer_length += 1;
3203                s.br.avail_in = s.buffer_length;
3204                (*input_offset) += 1;
3205                (*available_in) -= 1;
3206                // Retry with more data in buffer.
3207                // we can't re-borrow the saved buffer...so we have to do this recursively
3208                continue;
3209              }
3210              // Can't finish reading and no more input.
3211
3212              // FIXME :: NOT SURE WHAT THIS MEANT
3213              // saved_buffer = core::mem::replace(
3214              //  &mut s.br.input_,
3215              //  &mut[]); // clear input
3216              break;
3217            } else {
3218              // Input stream doesn't contain enough input.
3219              // Copy tail to internal buffer and return.
3220              *input_offset = s.br.next_in as usize;
3221              *available_in = s.br.avail_in as usize;
3222              let buffer_length = s.buffer_length as usize;
3223              let input_end = *input_offset as u64 + *available_in as u64;
3224              let buffer_end = buffer_length as u64 + *available_in as u64;
3225              if input_end > xinput.len() as u64 || buffer_end > s.buffer.len() as u64 {
3226                result = BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_UNREACHABLE;
3227                break;
3228              }
3229              let (input_end, buffer_end) = (input_end as usize, buffer_end as usize);
3230              s.buffer[buffer_length..buffer_end]
3231                .clone_from_slice(&xinput[*input_offset..input_end]);
3232              s.buffer_length = buffer_end as u32;
3233              *input_offset = input_end;
3234              *available_in = 0;
3235              break;
3236            }
3237            // unreachable!(); <- dead code
3238          }
3239          _ => {
3240            // Fail or needs more output.
3241            if s.buffer_length != 0 {
3242              // Just consumed the buffered input and produced some output. Otherwise
3243              // it would result in "needs more input". Reset internal buffer.
3244              s.buffer_length = 0;
3245            } else {
3246              // Using input stream in last iteration. When decoder switches to input
3247              // stream it has less than 8 bits in accamulator, so it is safe to
3248              // return unused accamulator bits there.
3249              bit_reader::BrotliBitReaderUnload(&mut s.br);
3250              *available_in = s.br.avail_in as usize;
3251              *input_offset = s.br.next_in as usize;
3252            }
3253          }
3254        }
3255        break;
3256      }
3257    }
3258    if !bit_reader::is_valid_bit_reader(&s.br, local_input) {
3259      result = BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_UNREACHABLE;
3260      continue;
3261    }
3262    loop {
3263      // this emulates fallthrough behavior
3264      match s.state {
3265        BrotliRunningState::BROTLI_STATE_UNINITED => {
3266          // Prepare to the first read.
3267          if (!bit_reader::BrotliWarmupBitReader(&mut s.br, local_input)) {
3268            result = BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT;
3269            break;
3270          }
3271          // Decode window size.
3272          /* Reads 1..8 bits. */
3273          result = DecodeWindowBits(&mut s.large_window, &mut s.window_bits, &mut s.br);
3274          match result {
3275            BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS => {}
3276            _ => break,
3277          }
3278          if s.large_window {
3279              s.state = BrotliRunningState::BROTLI_STATE_LARGE_WINDOW_BITS;
3280          } else {
3281              s.state = BrotliRunningState::BROTLI_STATE_INITIALIZE;
3282          }
3283        }
3284        BrotliRunningState::BROTLI_STATE_LARGE_WINDOW_BITS => {
3285          if (!bit_reader::BrotliSafeReadBits(&mut s.br, 6, &mut s.window_bits, local_input)) {
3286            result = BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT;
3287            break;
3288          }
3289          if (s.window_bits < kBrotliLargeMinWbits ||
3290              s.window_bits > kBrotliLargeMaxWbits) {
3291            result = BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS;
3292            break;
3293          }
3294          s.state = BrotliRunningState::BROTLI_STATE_INITIALIZE;
3295        }
3296        BrotliRunningState::BROTLI_STATE_INITIALIZE => {
3297          s.max_backward_distance = (1 << s.window_bits) - kBrotliWindowGap as i32;
3298          // A dictionary passed at construction time becomes a compound
3299          // dictionary chunk; it is kept in its own buffer rather than
3300          // prepended to the ring buffer so that it remains addressable
3301          // after the ring buffer wraps.
3302          if s.custom_dict.slice().len() != 0 {
3303            let dict = mem::replace(&mut s.custom_dict, AllocU8::AllocatedMemory::default());
3304            if !s.attach_compound_dictionary_chunk(state::MaybeOwnedSlice::Owned(dict)) {
3305              result = BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_COMPOUND_DICTIONARY;
3306              break;
3307            }
3308          }
3309
3310          // (formerly) Allocate memory for both block_type_trees and block_len_trees.
3311          s.block_type_length_state.block_type_trees = s.alloc_hc
3312            .alloc_cell(3 * huffman::BROTLI_HUFFMAN_MAX_TABLE_SIZE as usize);
3313          if (s.block_type_length_state.block_type_trees.slice().len() == 0) {
3314            result = BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_ALLOC_BLOCK_TYPE_TREES;
3315            break;
3316          }
3317          s.block_type_length_state.block_len_trees = s.alloc_hc
3318            .alloc_cell(3 * huffman::BROTLI_HUFFMAN_MAX_TABLE_SIZE as usize);
3319          if (s.block_type_length_state.block_len_trees.slice().len() == 0) {
3320            result = BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_ALLOC_BLOCK_TYPE_TREES;
3321            break;
3322          }
3323
3324          s.state = BrotliRunningState::BROTLI_STATE_METABLOCK_BEGIN;
3325          // No break, continue to next state
3326        }
3327        BrotliRunningState::BROTLI_STATE_METABLOCK_BEGIN => {
3328          s.BrotliStateMetablockBegin();
3329          BROTLI_LOG_UINT!(s.pos);
3330          s.state = BrotliRunningState::BROTLI_STATE_METABLOCK_HEADER;
3331          // No break, continue to next state
3332        }
3333        BrotliRunningState::BROTLI_STATE_METABLOCK_HEADER => {
3334          result = DecodeMetaBlockLength(&mut s, local_input); // Reads 2 - 31 bits.
3335          match result {
3336            BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS => {}
3337            _ => break,
3338          }
3339          BROTLI_LOG_UINT!(s.is_last_metablock);
3340          BROTLI_LOG_UINT!(s.meta_block_remaining_len);
3341          BROTLI_LOG_UINT!(s.is_metadata);
3342          BROTLI_LOG_UINT!(s.is_uncompressed);
3343          if (s.is_metadata != 0 || s.is_uncompressed != 0) &&
3344             !bit_reader::BrotliJumpToByteBoundary(&mut s.br) {
3345            result = BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_FORMAT_PADDING_2;
3346            break;
3347          }
3348          if s.is_metadata != 0 {
3349            s.state = BrotliRunningState::BROTLI_STATE_METADATA;
3350            break;
3351          }
3352          if s.meta_block_remaining_len == 0 {
3353            s.state = BrotliRunningState::BROTLI_STATE_METABLOCK_DONE;
3354            break;
3355          }
3356          if s.ringbuffer.slice().len() == 0 && !BrotliAllocateRingBuffer(&mut s, local_input) {
3357            result = BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_2;
3358            break;
3359          }
3360          if s.is_uncompressed != 0 {
3361            s.state = BrotliRunningState::BROTLI_STATE_UNCOMPRESSED;
3362            break;
3363          }
3364          s.loop_counter = 0;
3365          s.state = BrotliRunningState::BROTLI_STATE_HUFFMAN_CODE_0;
3366          break;
3367        }
3368        BrotliRunningState::BROTLI_STATE_UNCOMPRESSED => {
3369          let mut _bytes_copied = s.meta_block_remaining_len;
3370          result = CopyUncompressedBlockToOutput(&mut available_out,
3371                                                 &mut output,
3372                                                 &mut output_offset,
3373                                                 &mut total_out,
3374                                                 &mut s,
3375                                                 local_input);
3376          _bytes_copied -= s.meta_block_remaining_len;
3377          match result {
3378            BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS => {}
3379            _ => break,
3380          }
3381          s.state = BrotliRunningState::BROTLI_STATE_METABLOCK_DONE;
3382          break;
3383        }
3384        BrotliRunningState::BROTLI_STATE_METADATA => {
3385          while s.meta_block_remaining_len > 0 {
3386            let mut bits = 0u32;
3387            // Read one byte and ignore it.
3388            if !bit_reader::BrotliSafeReadBits(&mut s.br, 8, &mut bits, local_input) {
3389              result = BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT;
3390              break;
3391            }
3392            s.meta_block_remaining_len -= 1;
3393          }
3394          if let BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS = result {
3395            s.state = BrotliRunningState::BROTLI_STATE_METABLOCK_DONE
3396          }
3397          break;
3398        }
3399        BrotliRunningState::BROTLI_STATE_HUFFMAN_CODE_0 => {
3400          if s.loop_counter >= 3 {
3401            s.state = BrotliRunningState::BROTLI_STATE_METABLOCK_HEADER_2;
3402            break;
3403          }
3404          // Reads 1..11 bits.
3405          {
3406            let index = s.loop_counter as usize;
3407            result =
3408              DecodeVarLenUint8(&mut s.substate_decode_uint8,
3409                                &mut s.br,
3410                                &mut fast_mut!((s.block_type_length_state.num_block_types)[index]),
3411                                local_input);
3412          }
3413          match result {
3414            BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS => {}
3415            _ => break,
3416          }
3417          fast_mut!((s.block_type_length_state.num_block_types)[s.loop_counter as usize]) += 1;
3418          BROTLI_LOG_UINT!(s.block_type_length_state.num_block_types[s.loop_counter as usize]);
3419          if fast!((s.block_type_length_state.num_block_types)[s.loop_counter as usize]) < 2 {
3420            s.loop_counter += 1;
3421            break;
3422          }
3423          s.state = BrotliRunningState::BROTLI_STATE_HUFFMAN_CODE_1;
3424          // No break, continue to next state
3425        }
3426        BrotliRunningState::BROTLI_STATE_HUFFMAN_CODE_1 => {
3427          let tree_offset = s.loop_counter as u32 * huffman::BROTLI_HUFFMAN_MAX_TABLE_SIZE as u32;
3428          let mut new_huffman_table = mem::replace(&mut s.block_type_length_state.block_type_trees,
3429                                                   AllocHC::AllocatedMemory::default());
3430          let loop_counter = s.loop_counter as usize;
3431          let alphabet_size = fast!((s.block_type_length_state.num_block_types)[loop_counter]) + 2;
3432          result =
3433            ReadHuffmanCode(alphabet_size, alphabet_size,
3434                            new_huffman_table.slice_mut(),
3435                            tree_offset as usize,
3436                            None,
3437                            &mut s,
3438                            local_input);
3439          let _ = mem::replace(&mut s.block_type_length_state.block_type_trees,
3440                       new_huffman_table);
3441          match result {
3442            BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS => {}
3443            _ => break,
3444          }
3445          s.state = BrotliRunningState::BROTLI_STATE_HUFFMAN_CODE_2;
3446          // No break, continue to next state
3447        }
3448        BrotliRunningState::BROTLI_STATE_HUFFMAN_CODE_2 => {
3449          let tree_offset = s.loop_counter * huffman::BROTLI_HUFFMAN_MAX_TABLE_SIZE as i32;
3450          let mut new_huffman_table = mem::replace(&mut s.block_type_length_state.block_len_trees,
3451                                                   AllocHC::AllocatedMemory::default());
3452          result = ReadHuffmanCode(kNumBlockLengthCodes, kNumBlockLengthCodes,
3453                                   new_huffman_table.slice_mut(),
3454                                   tree_offset as usize,
3455                                   None,
3456                                   &mut s,
3457                                   local_input);
3458          let _ = mem::replace(&mut s.block_type_length_state.block_len_trees,
3459                       new_huffman_table);
3460          match result {
3461            BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS => {}
3462            _ => break,
3463          }
3464          s.state = BrotliRunningState::BROTLI_STATE_HUFFMAN_CODE_3;
3465          // No break, continue to next state
3466        }
3467        BrotliRunningState::BROTLI_STATE_HUFFMAN_CODE_3 => {
3468          let tree_offset = s.loop_counter * huffman::BROTLI_HUFFMAN_MAX_TABLE_SIZE as i32;
3469
3470          let mut block_length_out: u32 = 0;
3471          let ind_ret: (bool, u32);
3472          
3473          ind_ret = SafeReadBlockLengthIndex(&s.block_type_length_state.substate_read_block_length,
3474                                             s.block_type_length_state.block_length_index,
3475                                             fast_slice!((s.block_type_length_state.block_len_trees)
3476                                                           [tree_offset as usize;]),
3477                                             &mut s.br, local_input);
3478
3479          if !SafeReadBlockLengthFromIndex(&mut s.block_type_length_state,
3480                                           &mut s.br,
3481                                           &mut block_length_out,
3482                                           ind_ret,
3483                                           local_input) {
3484            result = BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT;
3485            break;
3486          }
3487          fast_mut!((s.block_type_length_state.block_length)[s.loop_counter as usize]) =
3488            block_length_out;
3489          BROTLI_LOG_UINT!(s.block_type_length_state.block_length[s.loop_counter as usize]);
3490          s.loop_counter += 1;
3491          s.state = BrotliRunningState::BROTLI_STATE_HUFFMAN_CODE_0;
3492          break;
3493        }
3494        BrotliRunningState::BROTLI_STATE_METABLOCK_HEADER_2 => {
3495          let mut bits: u32 = 0;
3496          if (!bit_reader::BrotliSafeReadBits(&mut s.br, 6, &mut bits, local_input)) {
3497            result = BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT;
3498            break;
3499          }
3500          s.distance_postfix_bits = bits & bit_reader::BitMask(2);
3501          bits >>= 2;
3502          s.num_direct_distance_codes = NUM_DISTANCE_SHORT_CODES +
3503                                        (bits << s.distance_postfix_bits);
3504          BROTLI_LOG_UINT!(s.num_direct_distance_codes);
3505          BROTLI_LOG_UINT!(s.distance_postfix_bits);
3506          s.distance_postfix_mask = bit_reader::BitMask(s.distance_postfix_bits) as i32;
3507          s.context_modes = s.alloc_u8
3508            .alloc_cell(fast!((s.block_type_length_state.num_block_types)[0]) as usize);
3509          if (s.context_modes.slice().len() == 0) {
3510            result = BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MODES;
3511            break;
3512          }
3513          s.loop_counter = 0;
3514          s.state = BrotliRunningState::BROTLI_STATE_CONTEXT_MODES;
3515          // No break, continue to next state
3516        }
3517        BrotliRunningState::BROTLI_STATE_CONTEXT_MODES => {
3518          result = ReadContextModes(&mut s, local_input);
3519          match result {
3520            BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS => {}
3521            _ => break,
3522          }
3523          s.state = BrotliRunningState::BROTLI_STATE_CONTEXT_MAP_1;
3524          // No break, continue to next state
3525        }
3526        BrotliRunningState::BROTLI_STATE_CONTEXT_MAP_1 => {
3527          result =
3528            DecodeContextMap((fast!((s.block_type_length_state.num_block_types)[0]) as usize) <<
3529                             kLiteralContextBits as usize,
3530                             false,
3531                             &mut s,
3532                             local_input);
3533          match result {
3534            BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS => {}
3535            _ => break,
3536          }
3537          DetectTrivialLiteralBlockTypes(s);
3538          s.state = BrotliRunningState::BROTLI_STATE_CONTEXT_MAP_2;
3539          // No break, continue to next state
3540        }
3541        BrotliRunningState::BROTLI_STATE_CONTEXT_MAP_2 => {
3542            let num_direct_codes =
3543              s.num_direct_distance_codes - NUM_DISTANCE_SHORT_CODES;
3544            let num_distance_codes = BROTLI_DISTANCE_ALPHABET_SIZE(
3545              s.distance_postfix_bits, num_direct_codes,
3546                (if s.large_window { BROTLI_LARGE_MAX_DISTANCE_BITS } else {
3547                    BROTLI_MAX_DISTANCE_BITS}));
3548            let max_distance_symbol = if s.large_window {
3549                BrotliMaxDistanceSymbol(
3550                    num_direct_codes, s.distance_postfix_bits)
3551            } else {
3552                num_distance_codes
3553            };
3554            result =
3555              DecodeContextMap((fast!((s.block_type_length_state.num_block_types)[2]) as usize) <<
3556                               kDistanceContextBits as usize,
3557                               true,
3558                               s,
3559                               local_input);
3560            match result {
3561              BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS => {}
3562              _ => break,
3563            }
3564            s.literal_hgroup.init(&mut s.alloc_u32,
3565                                  &mut s.alloc_hc,
3566                                  kNumLiteralCodes,
3567                                  kNumLiteralCodes,
3568                                  s.num_literal_htrees as u16);
3569            s.insert_copy_hgroup.init(&mut s.alloc_u32,
3570                                      &mut s.alloc_hc,
3571                                      kNumInsertAndCopyCodes,
3572                                      kNumInsertAndCopyCodes,
3573                                      fast!((s.block_type_length_state.num_block_types)[1]) as u16);
3574            s.distance_hgroup.init(&mut s.alloc_u32,
3575                                   &mut s.alloc_hc,
3576                                   num_distance_codes as u16,
3577                                   max_distance_symbol as u16,
3578                                   s.num_dist_htrees as u16);
3579            if (s.literal_hgroup.htrees.slice().len() == 0 ||
3580                s.literal_hgroup.codes.slice().len() == 0 ||
3581                s.insert_copy_hgroup.htrees.slice().len() == 0 ||
3582                s.insert_copy_hgroup.codes.slice().len() == 0 ||
3583                s.distance_hgroup.htrees.slice().len() == 0 ||
3584                s.distance_hgroup.codes.slice().len() == 0) {
3585              return SaveErrorCode!(
3586                s, BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_ALLOC_TREE_GROUPS);
3587            }
3588
3589          /*{
3590            let num_distance_codes: u32 = s.num_direct_distance_codes +
3591                                          (48u32 << s.distance_postfix_bits);
3592            result =
3593              DecodeContextMap((fast!((s.block_type_length_state.num_block_types)[2]) as usize) <<
3594                               kDistanceContextBits as usize,
3595                               true,
3596                               s,
3597                               local_input);
3598            match result {
3599              BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS => {}
3600              _ => break,
3601            }
3602            s.literal_hgroup.init(&mut s.alloc_u32,
3603                                  &mut s.alloc_hc,
3604                                  kNumLiteralCodes,
3605                                  s.num_literal_htrees as u16);
3606            s.insert_copy_hgroup.init(&mut s.alloc_u32,
3607                                      &mut s.alloc_hc,
3608                                      kNumInsertAndCopyCodes,
3609                                      fast!((s.block_type_length_state.num_block_types)[1]) as u16);
3610            s.distance_hgroup.init(&mut s.alloc_u32,
3611                                   &mut s.alloc_hc,
3612                                   num_distance_codes as u16,
3613                                   s.num_dist_htrees as u16);
3614            if (s.literal_hgroup.codes.slice().len() == 0 ||
3615                s.insert_copy_hgroup.codes.slice().len() == 0 ||
3616                s.distance_hgroup.codes.slice().len() == 0) {
3617              return SaveErrorCode!(s, BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_ALLOC_TREE_GROUPS);
3618            }
3619          }*/
3620          s.loop_counter = 0;
3621          s.state = BrotliRunningState::BROTLI_STATE_TREE_GROUP;
3622          // No break, continue to next state
3623        }
3624        BrotliRunningState::BROTLI_STATE_TREE_GROUP => {
3625          result = HuffmanTreeGroupDecode(s.loop_counter, &mut s, local_input);
3626          match result {
3627            BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS => {}
3628            _ => break,
3629          }
3630          s.loop_counter += 1;
3631          if (s.loop_counter >= 3) {
3632            PrepareLiteralDecoding(s);
3633            s.dist_context_map_slice_index = 0;
3634              /*
3635            s.context_map_slice_index = 0;
3636            let context_mode_index = fast!((s.block_type_length_state.block_type_rb)[1]);
3637            let context_mode = fast_slice!((s.context_modes)[context_mode_index as usize]);
3638            s.context_lookup = &kContextLookup[context_mode as usize & 3];
3639               */
3640            s.htree_command_index = 0;
3641            // look it up each time s.literal_htree=s.literal_hgroup.htrees[s.literal_htree_index];
3642            s.state = BrotliRunningState::BROTLI_STATE_COMMAND_BEGIN;
3643          }
3644          break;
3645        }
3646        BrotliRunningState::BROTLI_STATE_COMMAND_BEGIN |
3647        BrotliRunningState::BROTLI_STATE_COMMAND_INNER |
3648        BrotliRunningState::BROTLI_STATE_COMMAND_POST_DECODE_LITERALS |
3649        BrotliRunningState::BROTLI_STATE_COMMAND_POST_WRAP_COPY => {
3650          result = ProcessCommands(s, local_input);
3651          if let BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT = result {
3652            result = SafeProcessCommands(s, local_input)
3653          }
3654          break;
3655        }
3656        BrotliRunningState::BROTLI_STATE_COMMAND_INNER_WRITE |
3657        BrotliRunningState::BROTLI_STATE_COMMAND_POST_WRITE_1 |
3658        BrotliRunningState::BROTLI_STATE_COMMAND_POST_WRITE_2 => {
3659          let (xresult, _) = WriteRingBuffer(&mut available_out,
3660                                             Some(&mut output),
3661                                             &mut output_offset,
3662                                             &mut total_out,
3663                                             false,
3664                                             &mut s);
3665          result = xresult;
3666          match result {
3667            BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS => {}
3668            _ => break,
3669          }
3670          if !WrapRingBuffer(s) {
3671            result = BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_UNREACHABLE;
3672            break;
3673          }
3674          if s.ringbuffer_size == 1 << s.window_bits {
3675            s.max_distance = s.max_backward_distance;
3676          }
3677          match s.state {
3678            BrotliRunningState::BROTLI_STATE_COMMAND_POST_WRITE_1 => {
3679              if s.compound_dictionary.br_length != s.compound_dictionary.br_copied {
3680                // Resume an interrupted copy from the compound dictionary.
3681                let pos = s.pos;
3682                let copied = CopyFromCompoundDictionary(&mut s, pos);
3683                s.pos += copied;
3684                if s.pos >= s.ringbuffer_size {
3685                  // Ring buffer is full again; flush it and continue copying.
3686                  continue;
3687                }
3688              }
3689              if (s.meta_block_remaining_len <= 0) {
3690                // Next metablock, if any
3691                s.state = BrotliRunningState::BROTLI_STATE_METABLOCK_DONE;
3692              } else {
3693                s.state = BrotliRunningState::BROTLI_STATE_COMMAND_BEGIN;
3694              }
3695              break;
3696            }
3697            BrotliRunningState::BROTLI_STATE_COMMAND_POST_WRITE_2 => {
3698              s.state = BrotliRunningState::BROTLI_STATE_COMMAND_POST_WRAP_COPY;
3699            }
3700            _ => {
3701              // BROTLI_STATE_COMMAND_INNER_WRITE
3702              if (s.loop_counter == 0) {
3703                if (s.meta_block_remaining_len <= 0) {
3704                  s.state = BrotliRunningState::BROTLI_STATE_METABLOCK_DONE;
3705                } else {
3706                  s.state = BrotliRunningState::BROTLI_STATE_COMMAND_POST_DECODE_LITERALS;
3707                }
3708                break;
3709              }
3710              s.state = BrotliRunningState::BROTLI_STATE_COMMAND_INNER;
3711            }
3712          }
3713          break;
3714        }
3715        BrotliRunningState::BROTLI_STATE_METABLOCK_DONE => {
3716          // RFC 7932 §9.3: "if the number of literals to insert, the copy
3717          // length, or the resulting dictionary word length would cause MLEN to
3718          // be exceeded, then the stream should be rejected as invalid." When a
3719          // command overshoots the declared meta-block length, the command loop
3720          // exits to this state with meta_block_remaining_len < 0. The only
3721          // negative-length guard was in WriteRingBuffer, which is not reached
3722          // when the whole output fits in the ring buffer before the final
3723          // flush, so such malformed streams decoded as success. The C
3724          // reference and andybalholm/brotli (Go) reject them as BLOCK_LENGTH_2;
3725          // mirror that check here, before cleanup.
3726          if (s.meta_block_remaining_len < 0) {
3727            result = BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_2;
3728            break;
3729          }
3730          s.BrotliStateCleanupAfterMetablock();
3731          if (s.is_last_metablock == 0) {
3732            s.state = BrotliRunningState::BROTLI_STATE_METABLOCK_BEGIN;
3733            break;
3734          }
3735          if (!bit_reader::BrotliJumpToByteBoundary(&mut s.br)) {
3736            // RFC 7932 §9.2: padding bits at the end of the final metablock
3737            // must be zero. Without `break`, control falls through to
3738            // BROTLI_STATE_DONE which calls WriteRingBuffer and unconditionally
3739            // overwrites `result` with that call's return value, silently
3740            // dropping the padding error.
3741            result = BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_FORMAT_PADDING_2;
3742            break;
3743          }
3744          if (s.buffer_length == 0) {
3745            bit_reader::BrotliBitReaderUnload(&mut s.br);
3746            *available_in = s.br.avail_in as usize;
3747            *input_offset = s.br.next_in as usize;
3748          }
3749          s.state = BrotliRunningState::BROTLI_STATE_DONE;
3750          // No break, continue to next state
3751        }
3752        BrotliRunningState::BROTLI_STATE_DONE => {
3753          if (s.ringbuffer.slice().len() != 0) {
3754            let (xresult, _) = WriteRingBuffer(&mut available_out,
3755                                               Some(&mut output),
3756                                               &mut output_offset,
3757                                               &mut total_out,
3758                                               true,
3759                                               &mut s);
3760            result = xresult;
3761            match result {
3762              BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS => {}
3763              _ => break,
3764            }
3765          }
3766          return SaveErrorCode!(s, result);
3767        }
3768      }
3769    }
3770  }
3771
3772  SaveErrorCode!(s, result)
3773}
3774
3775#[cfg(test)]
3776mod safeguard_tests {
3777  use super::{memcpy_within_slice, memmove16};
3778
3779  #[test]
3780  fn memmove16_rejects_out_of_bounds_ranges() {
3781    let mut data = [0u8; 16];
3782    assert!(!memmove16(&mut data, 1, 0));
3783    assert!(!memmove16(&mut data, 0, 1));
3784  }
3785
3786  #[test]
3787  fn memcpy_within_slice_validates_nonoverlapping_ranges() {
3788    let mut data = [0u8, 1, 2, 3, 4, 5, 6, 7];
3789    assert!(memcpy_within_slice(&mut data, 4, 0, 2));
3790    assert_eq!(data, [0, 1, 2, 3, 0, 1, 6, 7]);
3791
3792    let unchanged = data;
3793    assert!(!memcpy_within_slice(&mut data, 1, 0, 4));
3794    assert!(!memcpy_within_slice(&mut data, 7, 0, 2));
3795    assert!(!memcpy_within_slice(&mut data, usize::MAX, 0, 2));
3796    assert!(!memcpy_within_slice(&mut data, 0, usize::MAX, 2));
3797    assert_eq!(data, unchanged);
3798  }
3799}
3800
3801// These need a live BrotliState, so they need an allocator: StandardAlloc is
3802// std-only, as in the `tests` module above.
3803#[cfg(all(test, feature="std"))]
3804mod state_guard_tests {
3805  use super::{CheckRingBufferConsistency, DecodeContextMap, ReadHuffmanCode, UnwrittenBytes,
3806              WrapRingBuffer, WriteRingBuffer};
3807  use super::{BrotliDecoderErrorCode, BrotliRunningState, BrotliState, HuffmanCode};
3808  use ::state::BrotliRunningHuffmanState;
3809  use ::alloc::Allocator;
3810  use ::StandardAlloc;
3811
3812  type TestState = BrotliState<StandardAlloc, StandardAlloc, StandardAlloc>;
3813
3814  fn state() -> TestState {
3815    BrotliState::new(StandardAlloc::default(), StandardAlloc::default(), StandardAlloc::default())
3816  }
3817
3818  // A decoder whose ring buffer is consistent: size is a power of two, mask is
3819  // size - 1, and the allocation is at least that long.
3820  fn state_with_ringbuffer(size: i32, window_bits: u32) -> TestState {
3821    let mut s = state();
3822    s.ringbuffer = s.alloc_u8.alloc_cell(size as usize);
3823    s.ringbuffer_size = size;
3824    s.ringbuffer_mask = size - 1;
3825    s.window_bits = window_bits;
3826    s
3827  }
3828
3829  // None of the guards below is reachable through BrotliDecompressStream, so
3830  // each is driven directly from an inconsistent decoder state. They exist
3831  // because the `unsafe` build turns an out-of-range index into an out-of-bounds
3832  // access rather than a panic.
3833
3834  #[test]
3835  fn ring_buffer_consistency_rejects_inconsistent_state() {
3836    let mut s = state_with_ringbuffer(16, 4);
3837    assert!(CheckRingBufferConsistency(&s));
3838
3839    s.pos = -1;
3840    assert!(!CheckRingBufferConsistency(&s));
3841    s.pos = 0;
3842
3843    s.ringbuffer_size = 0;
3844    assert!(!CheckRingBufferConsistency(&s));
3845    s.ringbuffer_size = 16;
3846
3847    s.ringbuffer_mask = -1;
3848    assert!(!CheckRingBufferConsistency(&s));
3849
3850    // mask that does not match the size
3851    s.ringbuffer_mask = 7;
3852    assert!(!CheckRingBufferConsistency(&s));
3853    s.ringbuffer_mask = 15;
3854
3855    // size larger than the allocation
3856    s.ringbuffer_size = 32;
3857    s.ringbuffer_mask = 31;
3858    assert!(!CheckRingBufferConsistency(&s));
3859  }
3860
3861  #[test]
3862  fn unwritten_bytes_is_exact_past_a_32_bit_wrap() {
3863    // rb_roundtrips * ringbuffer_size alone overflows a 32-bit usize, so this
3864    // only stays exact because the counters are u64.
3865    let mut s = state_with_ringbuffer(1 << 16, 16);
3866    s.rb_roundtrips = 1 << 17; // 2^17 * 2^16 == 2^33 bytes decoded
3867    s.pos = 100;
3868    s.partial_pos_out = (1u64 << 33) + 40;
3869    assert_eq!(UnwrittenBytes(&s, false), 60);
3870  }
3871
3872  #[test]
3873  fn write_ring_buffer_rejects_inconsistent_ring_buffer() {
3874    let mut s = state_with_ringbuffer(16, 4);
3875    s.ringbuffer_mask = 7; // no longer size - 1
3876    let mut available_out = 8usize;
3877    let mut output = [0u8; 8];
3878    let mut output_offset = 0usize;
3879    let mut total_out = 0usize;
3880    let (code, out) = WriteRingBuffer(&mut available_out, Some(&mut output[..]),
3881                                      &mut output_offset, &mut total_out, false, &mut s);
3882    match code {
3883      BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_UNREACHABLE => {}
3884      other => panic!("expected UNREACHABLE, got {:?}", other),
3885    }
3886    assert!(out.is_empty());
3887  }
3888
3889  #[test]
3890  fn write_ring_buffer_rejects_negative_block_length() {
3891    let mut s = state_with_ringbuffer(16, 4);
3892    s.meta_block_remaining_len = -1;
3893    let mut available_out = 0usize;
3894    let mut output_offset = 0usize;
3895    let mut total_out = 0usize;
3896    let (code, _) = WriteRingBuffer(&mut available_out, None, &mut output_offset,
3897                                    &mut total_out, false, &mut s);
3898    match code {
3899      BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_1 => {}
3900      other => panic!("expected BLOCK_LENGTH_1, got {:?}", other),
3901    }
3902  }
3903
3904  #[test]
3905  fn write_ring_buffer_rejects_output_slice_that_cannot_hold_the_write() {
3906    let mut s = state_with_ringbuffer(16, 4);
3907    s.pos = 8; // 8 bytes pending
3908    let mut available_out = 8usize;
3909    let mut output = [0u8; 8];
3910    // output_offset past the end of the caller's buffer: available_out claims
3911    // room the slice does not have.
3912    let mut output_offset = 4usize;
3913    let mut total_out = 0usize;
3914    let (code, _) = WriteRingBuffer(&mut available_out, Some(&mut output[..]),
3915                                    &mut output_offset, &mut total_out, false, &mut s);
3916    match code {
3917      BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_INVALID_ARGUMENTS => {}
3918      other => panic!("expected INVALID_ARGUMENTS, got {:?}", other),
3919    }
3920  }
3921
3922  #[test]
3923  fn wrap_ring_buffer_rejects_state_it_cannot_split() {
3924    let mut s = state_with_ringbuffer(16, 4);
3925    s.should_wrap_ringbuffer = true;
3926
3927    s.pos = -1;
3928    assert!(!WrapRingBuffer(&mut s));
3929
3930    s.pos = 0;
3931    s.ringbuffer_size = -1;
3932    assert!(!WrapRingBuffer(&mut s));
3933
3934    // size beyond the allocation
3935    s.ringbuffer_size = 64;
3936    s.pos = 1;
3937    assert!(!WrapRingBuffer(&mut s));
3938
3939    // pos past the tail region the wrap copies from
3940    s.ringbuffer_size = 16;
3941    s.pos = 8;
3942    assert!(!WrapRingBuffer(&mut s));
3943
3944    // and a state it can handle: half the buffer is the tail region
3945    let mut ok = state_with_ringbuffer(16, 4);
3946    ok.ringbuffer_size = 8;
3947    ok.ringbuffer_mask = 7;
3948    ok.pos = 4;
3949    ok.should_wrap_ringbuffer = true;
3950    assert!(WrapRingBuffer(&mut ok));
3951    assert!(!ok.should_wrap_ringbuffer);
3952  }
3953
3954  #[test]
3955  fn read_huffman_code_rejects_offset_past_table() {
3956    let mut s = state();
3957    let mut table = [HuffmanCode::default(); 4];
3958    let code = ReadHuffmanCode(256, 256, &mut table, 5, None, &mut s, &[]);
3959    match code {
3960      BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_FORMAT_HUFFMAN_SPACE => {}
3961      other => panic!("expected HUFFMAN_SPACE, got {:?}", other),
3962    }
3963  }
3964
3965  #[test]
3966  fn read_huffman_code_reports_a_simple_table_that_will_not_fit() {
3967    // The simple-code builder needs 1 << HUFFMAN_TABLE_BITS entries; a caller
3968    // slice shorter than that must surface as an error, not a partial table.
3969    let mut s = state();
3970    s.substate_huffman = BrotliRunningHuffmanState::BROTLI_STATE_HUFFMAN_SIMPLE_BUILD;
3971    s.symbol = 0;
3972    let mut table = [HuffmanCode::default(); 8];
3973    match ReadHuffmanCode(256, 256, &mut table, 0, None, &mut s, &[]) {
3974      BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_FORMAT_HUFFMAN_SPACE => {}
3975      other => panic!("expected HUFFMAN_SPACE, got {:?}", other),
3976    }
3977  }
3978
3979  #[test]
3980  fn read_huffman_code_reports_a_complex_table_that_will_not_fit() {
3981    let mut s = state();
3982    s.substate_huffman = BrotliRunningHuffmanState::BROTLI_STATE_HUFFMAN_LENGTH_SYMBOLS;
3983    // Nothing left to read, and a complete code, so the builder runs.
3984    s.symbol = 256;
3985    s.space = 0;
3986    s.code_length_histo[1] = 2;
3987    let mut table = [HuffmanCode::default(); 8];
3988    match ReadHuffmanCode(256, 256, &mut table, 0, None, &mut s, &[]) {
3989      BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_FORMAT_HUFFMAN_SPACE => {}
3990      other => panic!("expected HUFFMAN_SPACE, got {:?}", other),
3991    }
3992  }
3993
3994  #[test]
3995  fn read_huffman_code_reports_a_code_length_histogram_mismatch() {
3996    // Resuming BROTLI_STATE_HUFFMAN_COMPLEX with a histogram that does not
3997    // describe code_length_code_lengths is exactly what the builder's
3998    // consistency check exists to catch: without it the sort loop indexes
3999    // `sorted` out of bounds.
4000    let mut s = state();
4001    s.substate_huffman = BrotliRunningHuffmanState::BROTLI_STATE_HUFFMAN_COMPLEX;
4002    // Resume with every code-length code already read (sub_loop_counter at the
4003    // end of kCodeLengthCodeOrder) and a single code recorded, so
4004    // ReadCodeLengthCodeLengths returns success without consuming input.
4005    s.sub_loop_counter = super::CODE_LENGTH_CODES as u32;
4006    s.repeat = 1;
4007    s.space = 32;
4008    // ...but claim a length that code_length_code_lengths does not contain.
4009    s.code_length_histo[2] = 9;
4010    let mut table = [HuffmanCode::default(); 1080];
4011    match ReadHuffmanCode(256, 256, &mut table, 0, None, &mut s, &[]) {
4012      BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_FORMAT_HUFFMAN_SPACE => {}
4013      other => panic!("expected HUFFMAN_SPACE, got {:?}", other),
4014    }
4015  }
4016
4017  #[test]
4018  fn write_ring_buffer_rejects_a_pending_run_longer_than_the_ring() {
4019    // partial_pos_out lagging by more than one full ring makes `to_write`
4020    // exceed what actually lives in the buffer.
4021    let mut s = state_with_ringbuffer(16, 4);
4022    s.rb_roundtrips = 1;
4023    s.pos = 16;
4024    s.partial_pos_out = 4;
4025    let mut available_out = 64usize;
4026    let mut output = [0u8; 64];
4027    let mut output_offset = 0usize;
4028    let mut total_out = 0usize;
4029    let (code, _) = WriteRingBuffer(&mut available_out, Some(&mut output[..]),
4030                                    &mut output_offset, &mut total_out, false, &mut s);
4031    match code {
4032      BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_UNREACHABLE => {}
4033      other => panic!("expected UNREACHABLE, got {:?}", other),
4034    }
4035  }
4036
4037  #[test]
4038  fn write_ring_buffer_rejects_output_offset_that_would_overflow() {
4039    let mut s = state_with_ringbuffer(16, 4);
4040    s.pos = 8;
4041    let mut available_out = 8usize;
4042    let mut output_offset = usize::MAX - 1;
4043    let mut total_out = 0usize;
4044    let (code, _) = WriteRingBuffer(&mut available_out, None, &mut output_offset,
4045                                    &mut total_out, false, &mut s);
4046    match code {
4047      BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_INVALID_ARGUMENTS => {}
4048      other => panic!("expected INVALID_ARGUMENTS, got {:?}", other),
4049    }
4050  }
4051
4052  #[test]
4053  fn decode_context_map_rejects_mismatched_state() {
4054    let mut s = state();
4055    // Neither CONTEXT_MAP_1 with is_dist=false nor CONTEXT_MAP_2 with true.
4056    s.state = BrotliRunningState::BROTLI_STATE_CONTEXT_MAP_1;
4057    match DecodeContextMap(4, true, &mut s, &[]) {
4058      BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_UNREACHABLE => {}
4059      other => panic!("expected UNREACHABLE, got {:?}", other),
4060    }
4061    s.state = BrotliRunningState::BROTLI_STATE_CONTEXT_MAP_2;
4062    match DecodeContextMap(4, false, &mut s, &[]) {
4063      BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_UNREACHABLE => {}
4064      other => panic!("expected UNREACHABLE, got {:?}", other),
4065    }
4066    s.state = BrotliRunningState::BROTLI_STATE_UNINITED;
4067    match DecodeContextMap(4, false, &mut s, &[]) {
4068      BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_UNREACHABLE => {}
4069      other => panic!("expected UNREACHABLE, got {:?}", other),
4070    }
4071  }
4072}