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
8use 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
62const 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
143pub use state::BrotliState;
148fn 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 }
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 *value = bits;
230 *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 }
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 }
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 }
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 }
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 }
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 }
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#[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#[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
404fn 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; }
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; }
429 }
430 if (available_bits <= HUFFMAN_TABLE_BITS) {
431 return false; }
433
434 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; }
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#[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#[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
516fn 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 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
562fn 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 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
595fn 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
664fn 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); code_len = p.value as u32; 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 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 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; 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 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 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
803fn 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 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
860fn 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 alphabet_size &= 0x7ff;
888 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 if (s.sub_loop_counter != 1) {
901 s.space = 32;
902 s.repeat = 0; 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; }
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 continue;
913 }
914 s.substate_huffman = BrotliRunningHuffmanState::BROTLI_STATE_HUFFMAN_SIMPLE_SIZE;
915 }
917 BrotliRunningHuffmanState::BROTLI_STATE_HUFFMAN_SIMPLE_SIZE => {
918 if (!bit_reader::BrotliSafeReadBits(&mut s.br, 2, &mut s.symbol, input)) {
920 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 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 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 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; }
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 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
1032fn 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; fast_ref!((prefix::kBlockLengthPrefixCode)[code as usize]).offset as u32 +
1042 bit_reader::BrotliReadBits(br, nbits, input)
1043}
1044
1045
1046fn 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; 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
1098fn InverseMoveToFrontTransform(v: &mut [u8],
1114 v_len: u32,
1115 mtf: &mut [u8;256],
1116 mtf_upper_bound: &mut u32) {
1117 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 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 *mtf_upper_bound = upper_bound;
1145}
1146fn 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, }
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
1280fn 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 bzero(context_map_arg.slice_mut()); return BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS;
1320 }
1321 s.substate_context_map = BrotliRunningContextMapState::BROTLI_STATE_CONTEXT_MAP_READ_PREFIX;
1322 }
1324 BrotliRunningContextMapState::BROTLI_STATE_CONTEXT_MAP_READ_PREFIX => {
1325 let mut bits: u32 = 0;
1326 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 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 }
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 }
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; {
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 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 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 }
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
1484fn 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 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 let context_mode_index = fast!((s.context_modes.slice())[block_type]) & 3;
1586 s.context_lookup = &kContextLookup[context_mode_index as usize];
1587}
1588
1589fn 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}
1606fn 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
1658fn 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
1696fn 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
1716fn 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 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 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 *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 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 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 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 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 }
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 const kRingBufferWriteAheadSlack: i32 =
1893 SHARED_BROTLI_MAX_TRANSFORM_AFFIX_LENGTH as i32 + (SHARED_BROTLI_MAX_DICTIONARY_WORD_LENGTH as i32 + 1) + SHARED_BROTLI_MAX_TRANSFORM_AFFIX_LENGTH as i32; 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 ((next_block_header & 3) == 3) {
1907 is_last = 1;
1909 }
1910 }
1911 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
1934fn 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 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 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 }
1968
1969fn 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 while address as u32 >= fast!((addon.chunk_offsets)[index + 1]) {
1987 index += 1;
1988 }
1989 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
2000fn 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 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 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
2228pub 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 const kDistanceShortCodeIndexOffset: u32 = 0xaaafff1b;
2268 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 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#[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 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 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; 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 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 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 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 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 match status {
2546 BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS | BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_OUTPUT => {
2547 *size = requested_out - available_out;
2548 },
2549 _ => {
2550 if is_fatal(status) {
2553 }
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; 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 mark_unlikely();
2627 result = BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT;
2628 break; }
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; }
2636 s.state = BrotliRunningState::BROTLI_STATE_COMMAND_BEGIN;
2637 continue; }
2639 if (!ReadCommandInternal(safe, s, &mut i, input, &insert_copy_hgroup)) && safe {
2641 result = BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT;
2642 break; }
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; }
2650 s.meta_block_remaining_len -= i;
2651 s.state = BrotliRunningState::BROTLI_STATE_COMMAND_INNER;
2652 }
2653 BrotliRunningState::BROTLI_STATE_COMMAND_INNER => {
2654 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 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; }
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; }
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 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; }
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; }
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 } 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; }
2824 }
2825 if (!ReadDistanceInternal(safe, s, input, &distance_hgroup)) && safe {
2826 result = BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT;
2827 break; }
2829 }
2830 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 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 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; }
2858 pos += CopyFromCompoundDictionary(s, pos);
2859 if pos >= s.ringbuffer_size {
2860 s.state = BrotliRunningState::BROTLI_STATE_COMMAND_POST_WRITE_1;
2861 break; }
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 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 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; },
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; }
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; }
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.state = BrotliRunningState::BROTLI_STATE_COMMAND_POST_WRITE_1;
2949 break; }
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; }
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; }
2966 } else {
2967 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 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 if (src_end > pos as u32 && dst_end > src_start) {
2986 s.state = BrotliRunningState::BROTLI_STATE_COMMAND_POST_WRAP_COPY;
2987 continue; }
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; }
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 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 s.state = BrotliRunningState::BROTLI_STATE_METABLOCK_DONE;
3018 break; } else {
3020 s.state = BrotliRunningState::BROTLI_STATE_COMMAND_BEGIN;
3021 continue; }
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.state = BrotliRunningState::BROTLI_STATE_COMMAND_POST_WRITE_2;
3037 inner_return = true;
3038 break; }
3040 }
3041 if inner_return {
3042 mark_unlikely();
3043 break;
3044 }
3045 i -= 1;
3046 if (s.meta_block_remaining_len <= 0) {
3047 s.state = BrotliRunningState::BROTLI_STATE_METABLOCK_DONE;
3049 break; } else {
3051 s.state = BrotliRunningState::BROTLI_STATE_COMMAND_BEGIN;
3052 continue;
3053 }
3054 }
3055 _ => {
3056 result = BrotliDecoderErrorCode::BROTLI_DECODER_ERROR_UNREACHABLE;
3057 break; }
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
3098pub 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 if s.br.avail_in == 0 {
3180 s.buffer_length = 0;
3184 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 result = BrotliDecoderErrorCode::BROTLI_DECODER_SUCCESS;
3194 let new_byte = fast!((xinput)[*input_offset]);
3195 let buffer_length = s.buffer_length as usize;
3196 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 continue;
3209 }
3210 break;
3217 } else {
3218 *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 }
3239 _ => {
3240 if s.buffer_length != 0 {
3242 s.buffer_length = 0;
3245 } else {
3246 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 match s.state {
3265 BrotliRunningState::BROTLI_STATE_UNINITED => {
3266 if (!bit_reader::BrotliWarmupBitReader(&mut s.br, local_input)) {
3268 result = BrotliDecoderErrorCode::BROTLI_DECODER_NEEDS_MORE_INPUT;
3269 break;
3270 }
3271 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 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 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 }
3327 BrotliRunningState::BROTLI_STATE_METABLOCK_BEGIN => {
3328 s.BrotliStateMetablockBegin();
3329 BROTLI_LOG_UINT!(s.pos);
3330 s.state = BrotliRunningState::BROTLI_STATE_METABLOCK_HEADER;
3331 }
3333 BrotliRunningState::BROTLI_STATE_METABLOCK_HEADER => {
3334 result = DecodeMetaBlockLength(&mut s, local_input); 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 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 {
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 }
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 }
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 }
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 }
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 }
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 }
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 s.loop_counter = 0;
3621 s.state = BrotliRunningState::BROTLI_STATE_TREE_GROUP;
3622 }
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 s.htree_command_index = 0;
3641 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 let pos = s.pos;
3682 let copied = CopyFromCompoundDictionary(&mut s, pos);
3683 s.pos += copied;
3684 if s.pos >= s.ringbuffer_size {
3685 continue;
3687 }
3688 }
3689 if (s.meta_block_remaining_len <= 0) {
3690 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 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 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 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 }
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#[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 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 #[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 s.ringbuffer_mask = 7;
3852 assert!(!CheckRingBufferConsistency(&s));
3853 s.ringbuffer_mask = 15;
3854
3855 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 let mut s = state_with_ringbuffer(1 << 16, 16);
3866 s.rb_roundtrips = 1 << 17; 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; 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; let mut available_out = 8usize;
3909 let mut output = [0u8; 8];
3910 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 s.ringbuffer_size = 64;
3936 s.pos = 1;
3937 assert!(!WrapRingBuffer(&mut s));
3938
3939 s.ringbuffer_size = 16;
3941 s.pos = 8;
3942 assert!(!WrapRingBuffer(&mut s));
3943
3944 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 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 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 let mut s = state();
4001 s.substate_huffman = BrotliRunningHuffmanState::BROTLI_STATE_HUFFMAN_COMPLEX;
4002 s.sub_loop_counter = super::CODE_LENGTH_CODES as u32;
4006 s.repeat = 1;
4007 s.space = 32;
4008 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 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 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}