Coverage Report

Created: 2025-07-12 07:18

/rust/registry/src/index.crates.io-6f17d22bba15001f/zune-inflate-0.2.54/src/decoder.rs
Line
Count
Source (jump to first uncovered line)
1
#![allow(unused_imports)]
2
3
use alloc::vec::Vec;
4
use alloc::{format, vec};
5
6
use crate::bitstream::BitStreamReader;
7
use crate::constants::{
8
    DEFLATE_BLOCKTYPE_DYNAMIC_HUFFMAN, DEFLATE_BLOCKTYPE_RESERVED, DEFLATE_BLOCKTYPE_STATIC,
9
    DEFLATE_BLOCKTYPE_UNCOMPRESSED, DEFLATE_MAX_CODEWORD_LENGTH,
10
    DEFLATE_MAX_LITLEN_CODEWORD_LENGTH, DEFLATE_MAX_NUM_SYMS, DEFLATE_MAX_OFFSET_CODEWORD_LENGTH,
11
    DEFLATE_MAX_PRE_CODEWORD_LEN, DEFLATE_NUM_LITLEN_SYMS, DEFLATE_NUM_OFFSET_SYMS,
12
    DEFLATE_NUM_PRECODE_SYMS, DEFLATE_PRECODE_LENS_PERMUTATION, DELFATE_MAX_LENS_OVERRUN,
13
    FASTCOPY_BYTES, FASTLOOP_MAX_BYTES_WRITTEN, HUFFDEC_END_OF_BLOCK, HUFFDEC_EXCEPTIONAL,
14
    HUFFDEC_LITERAL, HUFFDEC_SUITABLE_POINTER, LITLEN_DECODE_BITS, LITLEN_DECODE_RESULTS,
15
    LITLEN_ENOUGH, LITLEN_TABLE_BITS, OFFSET_DECODE_RESULTS, OFFSET_ENOUGH, OFFSET_TABLEBITS,
16
    PRECODE_DECODE_RESULTS, PRECODE_ENOUGH, PRECODE_TABLE_BITS
17
};
18
use crate::errors::{DecodeErrorStatus, InflateDecodeErrors};
19
#[cfg(feature = "gzip")]
20
use crate::gzip_constants::{
21
    GZIP_CM_DEFLATE, GZIP_FCOMMENT, GZIP_FEXTRA, GZIP_FHCRC, GZIP_FNAME, GZIP_FOOTER_SIZE,
22
    GZIP_FRESERVED, GZIP_ID1, GZIP_ID2
23
};
24
use crate::utils::{copy_rep_matches, fixed_copy_within, make_decode_table_entry};
25
26
struct DeflateHeaderTables
27
{
28
    litlen_decode_table: [u32; LITLEN_ENOUGH],
29
    offset_decode_table: [u32; OFFSET_ENOUGH]
30
}
31
32
impl Default for DeflateHeaderTables
33
{
34
2
    fn default() -> Self
35
2
    {
36
2
        DeflateHeaderTables {
37
2
            litlen_decode_table: [0; LITLEN_ENOUGH],
38
2
            offset_decode_table: [0; OFFSET_ENOUGH]
39
2
        }
40
2
    }
41
}
42
43
/// Options that can influence decompression
44
/// in Deflate/Zlib/Gzip
45
///
46
/// To use them, pass a customized options to
47
/// the deflate decoder.
48
#[derive(Copy, Clone)]
49
pub struct DeflateOptions
50
{
51
    limit:            usize,
52
    confirm_checksum: bool,
53
    size_hint:        usize
54
}
55
56
impl Default for DeflateOptions
57
{
58
2
    fn default() -> Self
59
2
    {
60
2
        DeflateOptions {
61
2
            limit:            1 << 30,
62
2
            confirm_checksum: true,
63
2
            size_hint:        37000
64
2
        }
65
2
    }
66
}
67
68
impl DeflateOptions
69
{
70
    /// Get deflate/zlib limit option
71
    ///
72
    /// The decoder won't extend the inbuilt limit and will
73
    /// return an error if the limit is exceeded
74
    ///
75
    /// # Returns
76
    ///  The currently set limit of the instance
77
    /// # Note
78
    /// This is provided as a best effort, correctly quiting
79
    /// is detrimental to speed and hence this should not be relied too much.
80
0
    pub const fn get_limit(&self) -> usize
81
0
    {
82
0
        self.limit
83
0
    }
84
    /// Set a limit to the internal vector
85
    /// used to store decoded zlib/deflate output.
86
    ///
87
    /// # Arguments
88
    /// limit: The new decompressor limit
89
    /// # Returns
90
    /// A modified version of DeflateDecoder
91
    ///
92
    /// # Note
93
    /// This is provided as a best effort, correctly quiting
94
    /// is detrimental to speed and hence this should not be relied too much
95
    #[must_use]
96
2
    pub fn set_limit(mut self, limit: usize) -> Self
97
2
    {
98
2
        self.limit = limit;
99
2
        self
100
2
    }
101
102
    /// Get whether the decoder will confirm a checksum
103
    /// after decoding
104
0
    pub const fn get_confirm_checksum(&self) -> bool
105
0
    {
106
0
        self.confirm_checksum
107
0
    }
108
    /// Set whether the decoder should confirm a checksum
109
    /// after decoding
110
    ///
111
    /// Note, you should definitely confirm your checksum, use
112
    /// this with caution, otherwise data returned may be corrupt
113
    ///
114
    /// # Arguments
115
    /// - yes: When true, the decoder will confirm checksum
116
    /// when false, the decoder will skip checksum verification
117
    /// # Notes
118
    /// This does not have an influence for deflate decoding as
119
    /// it does not have a checksum
120
0
    pub fn set_confirm_checksum(mut self, yes: bool) -> Self
121
0
    {
122
0
        self.confirm_checksum = yes;
123
0
        self
124
0
    }
125
126
    /// Get the default set size hint for the decompressor
127
    ///
128
    /// The decompressor initializes the internal storage for decompressed bytes
129
    /// with this size and will reallocate the vec if the decompressed size becomes bigger
130
    /// than this, but when the user currently knows how big the output will be, can be used
131
    /// to prevent unnecessary re-allocations
132
0
    pub const fn get_size_hint(&self) -> usize
133
0
    {
134
0
        self.size_hint
135
0
    }
136
    /// Set the size hint for the decompressor
137
    ///
138
    /// This can be used to prevent multiple re-allocations
139
    #[must_use]
140
2
    pub const fn set_size_hint(mut self, hint: usize) -> Self
141
2
    {
142
2
        self.size_hint = hint;
143
2
        self
144
2
    }
145
}
146
147
/// A deflate decoder instance.
148
///
149
/// The decoder manages output buffer as opposed to requiring the caller to provide a pre-allocated buffer
150
/// it tracks number of bytes written and on successfully reaching the
151
/// end of the block, will return a vector with exactly
152
/// the number of decompressed bytes.
153
///
154
/// This means that it may use up huge amounts of memory if not checked, but
155
/// there are [options] that can prevent that
156
///
157
/// [options]: DeflateOptions
158
pub struct DeflateDecoder<'a>
159
{
160
    data:                  &'a [u8],
161
    position:              usize,
162
    stream:                BitStreamReader<'a>,
163
    is_last_block:         bool,
164
    static_codes_loaded:   bool,
165
    deflate_header_tables: DeflateHeaderTables,
166
    options:               DeflateOptions
167
}
168
169
impl<'a> DeflateDecoder<'a>
170
{
171
    /// Create a new decompressor that will read compressed
172
    /// data from `data` and return a new vector containing new data
173
    ///
174
    /// # Arguments
175
    /// - `data`: The compressed data. Data can be of any type
176
    /// gzip,zlib or raw deflate.
177
    ///
178
    /// # Returns
179
    /// A decoder instance which will pull compressed data from `data` to inflate the output output
180
    ///
181
    ///  # Note
182
    ///
183
    /// The default output size limit is **1 GiB.**
184
    /// this is to protect the end user against ddos attacks as deflate does not specify it's
185
    /// output size upfront
186
    ///
187
    /// The checksum will be verified depending on the called function.
188
    /// this only works for zlib and gzip since deflate does not have a checksum
189
    ///
190
    /// These defaults can be overridden via [new_with_options()](Self::new_with_options).
191
0
    pub fn new(data: &'a [u8]) -> DeflateDecoder<'a>
192
0
    {
193
0
        let options = DeflateOptions::default();
194
0
195
0
        Self::new_with_options(data, options)
196
0
    }
197
    /// Create new decoder with specified options
198
    ///
199
    /// This can be used to fine tune the decoder to the user's
200
    /// needs.
201
    ///
202
    ///
203
    /// # Arguments
204
    /// - `data`: The compressed data. Data can be of any format i.e
205
    /// gzip, zlib or raw deflate.
206
    /// - `options` : A set of user defined options which tune how the decompressor
207
    ///
208
    ///  # Returns
209
    /// A decoder instance which will pull compressed data from `data` to inflate output
210
    ///
211
    /// # Example
212
    /// ```no_run
213
    /// use zune_inflate::{DeflateDecoder, DeflateOptions};
214
    /// let data  = [37];
215
    /// let options = DeflateOptions::default()
216
    ///     .set_confirm_checksum(true) // confirm the checksum for zlib and gzip
217
    ///     .set_limit(1000); // how big I think the input will be    
218
    /// let mut decoder = DeflateDecoder::new_with_options(&data,options);
219
    /// // do some stuff and then call decode
220
    /// let data = decoder.decode_zlib();
221
    ///
222
    /// ```
223
2
    pub fn new_with_options(data: &'a [u8], options: DeflateOptions) -> DeflateDecoder<'a>
224
2
    {
225
2
        // create stream
226
2
        DeflateDecoder {
227
2
            data,
228
2
            position: 0,
229
2
            stream: BitStreamReader::new(data),
230
2
            is_last_block: false,
231
2
            static_codes_loaded: false,
232
2
            deflate_header_tables: DeflateHeaderTables::default(),
233
2
            options
234
2
        }
235
2
    }
236
    /// Decode zlib-encoded data returning the uncompressed in a `Vec<u8>`
237
    /// or an error if something went wrong.
238
    ///
239
    /// Bytes consumed will be from the data passed when the
240
    /// `new` method was called.
241
    ///
242
    /// # Arguments
243
    /// - None
244
    /// # Returns
245
    /// Result type containing the decoded data.
246
    ///
247
    /// - `Ok(Vec<u8>)`: Decoded vector containing the uncompressed bytes
248
    /// - `Err(InflateDecodeErrors)`: Error that occurred during decoding
249
    ///
250
    /// It's possible to recover bytes even after an error occurred, bytes up
251
    /// to when error was encountered are stored in [InflateDecodeErrors]
252
    ///
253
    ///
254
    /// # Note
255
    /// This needs the `zlib` feature enabled to be available otherwise it's a
256
    /// compile time error
257
    ///
258
    /// [InflateDecodeErrors]:crate::errors::InflateDecodeErrors
259
    ///
260
    #[cfg(feature = "zlib")]
261
2
    pub fn decode_zlib(&mut self) -> Result<Vec<u8>, InflateDecodeErrors>
262
2
    {
263
        use crate::utils::calc_adler_hash;
264
265
2
        if self.data.len()
266
2
            < 2 /* zlib header */
267
2
            + 4
268
        /* Deflate */
269
        {
270
2
            return Err(InflateDecodeErrors::new_with_error(
271
2
                DecodeErrorStatus::InsufficientData
272
2
            ));
273
0
        }
274
0
275
0
        // Zlib flags
276
0
        // See https://www.ietf.org/rfc/rfc1950.txt for
277
0
        // the RFC
278
0
        let cmf = self.data[0];
279
0
        let flg = self.data[1];
280
0
281
0
        let cm = cmf & 0xF;
282
0
        let cinfo = cmf >> 4;
283
0
284
0
        // let fcheck = flg & 0xF;
285
0
        // let fdict = (flg >> 4) & 1;
286
0
        // let flevel = flg >> 5;
287
0
288
0
        // confirm we have the right deflate methods
289
0
        if cm != 8
290
        {
291
0
            if cm == 15
292
            {
293
0
                return Err(InflateDecodeErrors::new_with_error(DecodeErrorStatus::Generic(
294
0
                    "CM of 15 is preserved by the standard,currently don't know how to handle it"
295
0
                )));
296
0
            }
297
0
            return Err(InflateDecodeErrors::new_with_error(
298
0
                DecodeErrorStatus::GenericStr(format!("Unknown zlib compression method {cm}"))
299
0
            ));
300
0
        }
301
0
        if cinfo > 7
302
        {
303
0
            return Err(InflateDecodeErrors::new_with_error(
304
0
                DecodeErrorStatus::GenericStr(format!(
305
0
                    "Unknown cinfo `{cinfo}` greater than 7, not allowed"
306
0
                ))
307
0
            ));
308
0
        }
309
0
        let flag_checks = (u16::from(cmf) * 256) + u16::from(flg);
310
0
311
0
        if flag_checks % 31 != 0
312
        {
313
0
            return Err(InflateDecodeErrors::new_with_error(
314
0
                DecodeErrorStatus::Generic("FCHECK integrity not preserved")
315
0
            ));
316
0
        }
317
0
318
0
        self.position = 2;
319
320
0
        let data = self.decode_deflate()?;
321
322
0
        if self.options.confirm_checksum
323
        {
324
            // Get number of consumed bytes from the input
325
0
            let out_pos = self.stream.get_position() + self.position + self.stream.over_read;
326
327
            // read adler
328
0
            if let Some(adler) = self.data.get(out_pos..out_pos + 4)
329
            {
330
0
                let adler_bits: [u8; 4] = adler.try_into().unwrap();
331
0
332
0
                let adler32_expected = u32::from_be_bytes(adler_bits);
333
0
334
0
                let adler32_found = calc_adler_hash(&data);
335
0
336
0
                if adler32_expected != adler32_found
337
                {
338
0
                    let err_msg =
339
0
                        DecodeErrorStatus::MismatchedAdler(adler32_expected, adler32_found);
340
0
                    let err = InflateDecodeErrors::new(err_msg, data);
341
0
342
0
                    return Err(err);
343
0
                }
344
            }
345
            else
346
            {
347
0
                let err = InflateDecodeErrors::new(DecodeErrorStatus::InsufficientData, data);
348
0
349
0
                return Err(err);
350
            }
351
0
        }
352
353
0
        Ok(data)
354
2
    }
355
356
    /// Decode a gzip encoded data and return the uncompressed data in a
357
    /// `Vec<u8>` or an error if something went wrong
358
    ///
359
    /// Bytes consumed will be from the data passed when the
360
    /// `new` method was called.
361
    ///
362
    /// # Arguments
363
    /// - None
364
    /// # Returns
365
    /// Result type containing the decoded data.
366
    ///
367
    /// - `Ok(Vec<u8>)`: Decoded vector containing the uncompressed bytes
368
    /// - `Err(InflateDecodeErrors)`: Error that occurred during decoding
369
    ///
370
    /// It's possible to recover bytes even after an error occurred, bytes up
371
    /// to when error was encountered are stored in [InflateDecodeErrors]
372
    ///
373
    /// # Note
374
    /// This needs the `gzip` feature enabled to be available, otherwise it's a
375
    /// compile time error
376
    ///
377
    /// [InflateDecodeErrors]:crate::errors::InflateDecodeErrors
378
    ///
379
    #[cfg(feature = "gzip")]
380
    pub fn decode_gzip(&mut self) -> Result<Vec<u8>, InflateDecodeErrors>
381
    {
382
        if self.data.len() < 18
383
        {
384
            return Err(InflateDecodeErrors::new_with_error(
385
                DecodeErrorStatus::InsufficientData
386
            ));
387
        }
388
389
        if self.data[self.position] != GZIP_ID1
390
        {
391
            return Err(InflateDecodeErrors::new_with_error(
392
                DecodeErrorStatus::CorruptData
393
            ));
394
        }
395
        self.position += 1;
396
        if self.data[self.position] != GZIP_ID2
397
        {
398
            return Err(InflateDecodeErrors::new_with_error(
399
                DecodeErrorStatus::CorruptData
400
            ));
401
        }
402
        self.position += 1;
403
404
        if self.data[self.position] != GZIP_CM_DEFLATE
405
        {
406
            return Err(InflateDecodeErrors::new_with_error(
407
                DecodeErrorStatus::CorruptData
408
            ));
409
        }
410
        self.position += 1;
411
412
        let flg = self.data[self.position];
413
        self.position += 1;
414
415
        // skip mtime
416
        self.position += 4;
417
        // skip xfl
418
        self.position += 1;
419
        // skip os
420
        self.position += 1;
421
422
        if (flg & GZIP_FRESERVED) != 0
423
        {
424
            return Err(InflateDecodeErrors::new_with_error(
425
                DecodeErrorStatus::CorruptData
426
            ));
427
        }
428
        // extra field
429
        if (flg & GZIP_FEXTRA) != 0
430
        {
431
            let len_bytes = self.data[self.position..self.position + 2]
432
                .try_into()
433
                .unwrap();
434
            let xlen = usize::from(u16::from_le_bytes(len_bytes));
435
436
            self.position += 2;
437
438
            if self.data.len().saturating_sub(self.position) < xlen + GZIP_FOOTER_SIZE
439
            {
440
                return Err(InflateDecodeErrors::new_with_error(
441
                    DecodeErrorStatus::CorruptData
442
                ));
443
            }
444
            self.position += xlen;
445
        }
446
        // original file name zero terminated
447
        if (flg & GZIP_FNAME) != 0
448
        {
449
            loop
450
            {
451
                if let Some(byte) = self.data.get(self.position)
452
                {
453
                    self.position += 1;
454
455
                    if *byte == 0
456
                    {
457
                        break;
458
                    }
459
                }
460
                else
461
                {
462
                    return Err(InflateDecodeErrors::new_with_error(
463
                        DecodeErrorStatus::InsufficientData
464
                    ));
465
                }
466
            }
467
        }
468
        // File comment zero terminated
469
        if (flg & GZIP_FCOMMENT) != 0
470
        {
471
            loop
472
            {
473
                if let Some(byte) = self.data.get(self.position)
474
                {
475
                    self.position += 1;
476
477
                    if *byte == 0
478
                    {
479
                        break;
480
                    }
481
                }
482
                else
483
                {
484
                    return Err(InflateDecodeErrors::new_with_error(
485
                        DecodeErrorStatus::InsufficientData
486
                    ));
487
                }
488
            }
489
        }
490
        // crc16 for gzip header
491
        if (flg & GZIP_FHCRC) != 0
492
        {
493
            self.position += 2;
494
        }
495
496
        if self.position + GZIP_FOOTER_SIZE > self.data.len()
497
        {
498
            return Err(InflateDecodeErrors::new_with_error(
499
                DecodeErrorStatus::InsufficientData
500
            ));
501
        }
502
503
        let data = self.decode_deflate()?;
504
505
        let mut out_pos = self.stream.get_position() + self.position + self.stream.over_read;
506
507
        if self.options.confirm_checksum
508
        {
509
            // Get number of consumed bytes from the input
510
511
            if let Some(crc) = self.data.get(out_pos..out_pos + 4)
512
            {
513
                let crc_bits: [u8; 4] = crc.try_into().unwrap();
514
515
                let crc32_expected = u32::from_le_bytes(crc_bits);
516
517
                let crc32_found = !crate::crc::crc32(&data, !0);
518
519
                if crc32_expected != crc32_found
520
                {
521
                    let err_msg = DecodeErrorStatus::MismatchedCRC(crc32_expected, crc32_found);
522
                    let err = InflateDecodeErrors::new(err_msg, data);
523
524
                    return Err(err);
525
                }
526
            }
527
            else
528
            {
529
                let err = InflateDecodeErrors::new(DecodeErrorStatus::InsufficientData, data);
530
531
                return Err(err);
532
            }
533
        }
534
        //checksum
535
        out_pos += 4;
536
537
        if let Some(val) = self.data.get(out_pos..out_pos + 4)
538
        {
539
            let actual_bytes: [u8; 4] = val.try_into().unwrap();
540
            let ac = u32::from_le_bytes(actual_bytes) as usize;
541
542
            if data.len() != ac
543
            {
544
                let err = DecodeErrorStatus::Generic("ISIZE does not match actual bytes");
545
546
                let err = InflateDecodeErrors::new(err, data);
547
548
                return Err(err);
549
            }
550
        }
551
        else
552
        {
553
            let err = InflateDecodeErrors::new(DecodeErrorStatus::InsufficientData, data);
554
555
            return Err(err);
556
        }
557
558
        Ok(data)
559
    }
560
    /// Decode a deflate stream returning the data as `Vec<u8>` or an error
561
    /// indicating what went wrong.
562
    /// # Arguments
563
    /// - None
564
    /// # Returns
565
    /// Result type containing the decoded data.
566
    ///
567
    /// - `Ok(Vec<u8>)`: Decoded vector containing the uncompressed bytes
568
    /// - `Err(InflateDecodeErrors)`: Error that occurred during decoding
569
    ///
570
    /// It's possible to recover bytes even after an error occurred, bytes up
571
    /// to when error was encountered are stored in [InflateDecodeErrors]
572
    ///
573
    ///
574
    /// # Example
575
    /// ```no_run
576
    /// let data = [42]; // answer to life, the universe and everything
577
    ///
578
    /// let mut decoder = zune_inflate::DeflateDecoder::new(&data);
579
    /// let bytes = decoder.decode_deflate().unwrap();
580
    /// ```
581
    ///
582
    ///  [InflateDecodeErrors]:crate::errors::InflateDecodeErrors
583
0
    pub fn decode_deflate(&mut self) -> Result<Vec<u8>, InflateDecodeErrors>
584
0
    {
585
0
        self.start_deflate_block()
586
0
    }
587
    /// Main inner loop for decompressing deflate data
588
    #[allow(unused_assignments)]
589
0
    fn start_deflate_block(&mut self) -> Result<Vec<u8>, InflateDecodeErrors>
590
0
    {
591
0
        // start deflate decode
592
0
        // re-read the stream so that we can remove code read by zlib
593
0
        self.stream = BitStreamReader::new(&self.data[self.position..]);
594
0
595
0
        self.stream.refill();
596
0
597
0
        // Output space for our decoded bytes.
598
0
        let mut out_block = vec![0; self.options.size_hint];
599
0
        // bits used
600
0
601
0
        let mut src_offset = 0;
602
0
        let mut dest_offset = 0;
603
604
        loop
605
        {
606
0
            self.stream.refill();
607
0
608
0
            self.is_last_block = self.stream.get_bits(1) == 1;
609
0
            let block_type = self.stream.get_bits(2);
610
0
611
0
            if block_type == DEFLATE_BLOCKTYPE_UNCOMPRESSED
612
            {
613
                /*
614
                 * Uncompressed block: copy 'len' bytes literally from the input
615
                 * buffer to the output buffer.
616
                 */
617
                /*
618
                 * The RFC says that
619
                 * skip any remaining bits in current partially
620
                 *       processed byte
621
                 *     read LEN and NLEN (see next section)
622
                 *     copy LEN bytes of data to output
623
                 */
624
625
0
                if self.stream.over_read > usize::from(self.stream.get_bits_left() >> 3)
626
                {
627
0
                    out_block.truncate(dest_offset);
628
0
629
0
                    let err_msg = DecodeErrorStatus::Generic("over-read stream");
630
0
                    let error = InflateDecodeErrors::new(err_msg, out_block);
631
0
632
0
                    return Err(error);
633
0
                }
634
0
                let partial_bits = self.stream.get_bits_left() & 7;
635
0
636
0
                self.stream.drop_bits(partial_bits);
637
0
638
0
                let len = self.stream.get_bits(16) as u16;
639
0
                let nlen = self.stream.get_bits(16) as u16;
640
0
641
0
                // copy to deflate
642
0
                if len != !nlen
643
                {
644
0
                    out_block.truncate(dest_offset);
645
0
646
0
                    let err_msg = DecodeErrorStatus::Generic("Len and nlen do not match");
647
0
                    let error = InflateDecodeErrors::new(err_msg, out_block);
648
0
649
0
                    return Err(error);
650
0
                }
651
0
                let len = len as usize;
652
0
653
0
                let start = self.stream.get_position() + self.position + self.stream.over_read;
654
0
655
0
                // ensure there is enough space for a fast copy
656
0
                if dest_offset + len + FASTCOPY_BYTES > out_block.len()
657
0
                {
658
0
                    // and if there is not, resize
659
0
                    let new_len = out_block.len() + RESIZE_BY + len;
660
0
661
0
                    out_block.resize(new_len, 0);
662
0
                }
663
664
0
                if self.data.get((start + len).saturating_sub(1)).is_none()
665
                {
666
0
                    out_block.truncate(dest_offset);
667
0
668
0
                    let err_msg = DecodeErrorStatus::CorruptData;
669
0
                    let error = InflateDecodeErrors::new(err_msg, out_block);
670
0
671
0
                    return Err(error);
672
0
                }
673
0
                if dest_offset > self.options.limit
674
                {
675
0
                    out_block.truncate(dest_offset);
676
0
677
0
                    let err_msg =
678
0
                        DecodeErrorStatus::OutputLimitExceeded(self.options.limit, out_block.len());
679
0
                    let error = InflateDecodeErrors::new(err_msg, out_block);
680
0
681
0
                    return Err(error);
682
0
                }
683
0
684
0
                out_block[dest_offset..dest_offset + len]
685
0
                    .copy_from_slice(&self.data[start..start + len]);
686
0
687
0
                dest_offset += len;
688
0
689
0
                // get the new position to write.
690
0
                self.stream.position =
691
0
                    len + (self.stream.position - usize::from(self.stream.bits_left >> 3));
692
0
693
0
                self.stream.reset();
694
0
695
0
                if self.is_last_block
696
                {
697
0
                    break;
698
0
                }
699
0
700
0
                continue;
701
            }
702
0
            else if block_type == DEFLATE_BLOCKTYPE_RESERVED
703
            {
704
0
                out_block.truncate(dest_offset);
705
0
706
0
                let err_msg = DecodeErrorStatus::Generic("Reserved block type 0b11 encountered");
707
0
                let error = InflateDecodeErrors::new(err_msg, out_block);
708
0
709
0
                return Err(error);
710
0
            }
711
0
712
0
            // build decode tables for static and dynamic tables
713
0
            match self.build_decode_table(block_type)
714
            {
715
0
                Ok(_) => (),
716
0
                Err(value) =>
717
0
                {
718
0
                    out_block.truncate(dest_offset);
719
0
720
0
                    let err_msg = value;
721
0
                    let error = InflateDecodeErrors::new(err_msg, out_block);
722
0
723
0
                    return Err(error);
724
                }
725
            };
726
727
            // Tables are mutated into the struct, so at this point we know the tables
728
            // are loaded, take a reference to them
729
0
            let litlen_decode_table = &self.deflate_header_tables.litlen_decode_table;
730
0
            let offset_decode_table = &self.deflate_header_tables.offset_decode_table;
731
0
732
0
            /*
733
0
             * This is the "fast loop" for decoding literals and matches.  It does
734
0
             * bounds checks on in_next and out_next in the loop conditions so that
735
0
             * additional bounds checks aren't needed inside the loop body.
736
0
             *
737
0
             * To reduce latency, the bit-buffer is refilled and the next litlen
738
0
             * decode table entry is preloaded before each loop iteration.
739
0
             */
740
0
            let (mut literal, mut length, mut offset, mut entry) = (0, 0, 0, 0);
741
0
742
0
            let mut saved_bitbuf;
743
0
744
0
            'decode: loop
745
0
            {
746
0
                let close_src = 3 * FASTCOPY_BYTES < self.stream.remaining_bytes();
747
0
748
0
                if close_src
749
                {
750
0
                    self.stream.refill_inner_loop();
751
0
752
0
                    let lit_mask = self.stream.peek_bits::<LITLEN_DECODE_BITS>();
753
0
754
0
                    entry = litlen_decode_table[lit_mask];
755
756
                    'sequence: loop
757
                    {
758
                        // Resize the output vector here to ensure we can always have
759
                        // enough space for sloppy copies
760
0
                        if dest_offset + FASTLOOP_MAX_BYTES_WRITTEN > out_block.len()
761
                        {
762
0
                            let curr_len = out_block.len();
763
0
                            out_block.resize(curr_len + FASTLOOP_MAX_BYTES_WRITTEN + RESIZE_BY, 0)
764
0
                        }
765
                        // At this point entry contains the next value of the litlen
766
                        // This will always be the case so meaning all our exit paths need
767
                        // to load in the next entry.
768
769
                        // recheck after every sequence
770
                        // when we hit continue, we need to recheck this
771
                        // as we are trying to emulate a do while
772
0
                        let new_check = self.stream.src.len() < self.stream.position + 8;
773
0
774
0
                        if new_check
775
                        {
776
0
                            break 'sequence;
777
0
                        }
778
0
779
0
                        self.stream.refill_inner_loop();
780
0
                        /*
781
0
                         * Consume the bits for the litlen decode table entry.  Save the
782
0
                         * original bit-buf for later, in case the extra match length
783
0
                         * bits need to be extracted from it.
784
0
                         */
785
0
                        saved_bitbuf = self.stream.buffer;
786
0
787
0
                        self.stream.drop_bits((entry & 0xFF) as u8);
788
0
789
0
                        /*
790
0
                         * Begin by checking for a "fast" literal, i.e. a literal that
791
0
                         * doesn't need a subtable.
792
0
                         */
793
0
                        if (entry & HUFFDEC_LITERAL) != 0
794
                        {
795
                            /*
796
                             * On 64-bit platforms, we decode up to 2 extra fast
797
                             * literals in addition to the primary item, as this
798
                             * increases performance and still leaves enough bits
799
                             * remaining for what follows.  We could actually do 3,
800
                             * assuming LITLEN_TABLEBITS=11, but that actually
801
                             * decreases performance slightly (perhaps by messing
802
                             * with the branch prediction of the conditional refill
803
                             * that happens later while decoding the match offset).
804
                             */
805
806
0
                            literal = entry >> 16;
807
0
808
0
                            let new_pos = self.stream.peek_bits::<LITLEN_DECODE_BITS>();
809
0
810
0
                            entry = litlen_decode_table[new_pos];
811
0
                            saved_bitbuf = self.stream.buffer;
812
0
813
0
                            self.stream.drop_bits(entry as u8);
814
0
815
0
                            let out: &mut [u8; 2] = out_block
816
0
                                .get_mut(dest_offset..dest_offset + 2)
817
0
                                .unwrap()
818
0
                                .try_into()
819
0
                                .unwrap();
820
0
821
0
                            out[0] = literal as u8;
822
0
                            dest_offset += 1;
823
0
824
0
                            if (entry & HUFFDEC_LITERAL) != 0
825
                            {
826
                                /*
827
                                 * Another fast literal, but this one is in lieu of the
828
                                 * primary item, so it doesn't count as one of the extras.
829
                                 */
830
831
                                // load in the next entry.
832
0
                                literal = entry >> 16;
833
0
834
0
                                let new_pos = self.stream.peek_bits::<LITLEN_DECODE_BITS>();
835
0
836
0
                                entry = litlen_decode_table[new_pos];
837
0
838
0
                                out[1] = literal as u8;
839
0
                                dest_offset += 1;
840
0
841
0
                                continue;
842
0
                            }
843
0
                        }
844
                        /*
845
                         * It's not a literal entry, so it can be a length entry, a
846
                         * subtable pointer entry, or an end-of-block entry.  Detect the
847
                         * two unlikely cases by testing the HUFFDEC_EXCEPTIONAL flag.
848
                         */
849
0
                        if (entry & HUFFDEC_EXCEPTIONAL) != 0
850
                        {
851
                            // Subtable pointer or end of block entry
852
0
                            if (entry & HUFFDEC_END_OF_BLOCK) != 0
853
                            {
854
                                // block done
855
0
                                break 'decode;
856
0
                            }
857
0
                            /*
858
0
                             * A subtable is required.  Load and consume the
859
0
                             * subtable entry.  The subtable entry can be of any
860
0
                             * type: literal, length, or end-of-block.
861
0
                             */
862
0
                            let entry_position = ((entry >> 8) & 0x3F) as usize;
863
0
                            let mut pos = (entry >> 16) as usize;
864
0
865
0
                            saved_bitbuf = self.stream.buffer;
866
0
867
0
                            pos += self.stream.peek_var_bits(entry_position);
868
0
                            entry = litlen_decode_table[pos.min(LITLEN_ENOUGH - 1)];
869
0
870
0
                            self.stream.drop_bits(entry as u8);
871
0
872
0
                            if (entry & HUFFDEC_LITERAL) != 0
873
                            {
874
                                // decode a literal that required a sub table
875
0
                                let new_pos = self.stream.peek_bits::<LITLEN_DECODE_BITS>();
876
0
877
0
                                literal = entry >> 16;
878
0
                                entry = litlen_decode_table[new_pos];
879
0
880
0
                                *out_block.get_mut(dest_offset).unwrap_or(&mut 0) =
881
0
                                    (literal & 0xFF) as u8;
882
0
883
0
                                dest_offset += 1;
884
0
885
0
                                continue;
886
0
                            }
887
0
888
0
                            if (entry & HUFFDEC_END_OF_BLOCK) != 0
889
                            {
890
0
                                break 'decode;
891
0
                            }
892
0
                        }
893
894
                        //  At this point,we dropped at most 22 bits(LITLEN_DECODE is 11 and we
895
                        // can do it twice), we now just have 34 bits min remaining.
896
897
                        /*
898
                         * Decode the match length: the length base value associated
899
                         * with the litlen symbol (which we extract from the decode
900
                         * table entry), plus the extra length bits.  We don't need to
901
                         * consume the extra length bits here, as they were included in
902
                         * the bits consumed by the entry earlier.  We also don't need
903
                         * to check for too-long matches here, as this is inside the
904
                         * fast loop where it's already been verified that the output
905
                         * buffer has enough space remaining to copy a max-length match.
906
                         */
907
0
                        let entry_dup = entry;
908
0
909
0
                        entry = offset_decode_table[self.stream.peek_bits::<OFFSET_TABLEBITS>()];
910
0
                        length = (entry_dup >> 16) as usize;
911
0
912
0
                        let mask = (1 << entry_dup as u8) - 1;
913
0
914
0
                        length += (saved_bitbuf & mask) as usize >> ((entry_dup >> 8) as u8);
915
0
916
0
                        // offset requires a subtable
917
0
                        if (entry & HUFFDEC_EXCEPTIONAL) != 0
918
0
                        {
919
0
                            self.stream.drop_bits(OFFSET_TABLEBITS as u8);
920
0
                            let extra = self.stream.peek_var_bits(((entry >> 8) & 0x3F) as usize);
921
0
                            entry = offset_decode_table[((entry >> 16) as usize + extra) & 511];
922
0
                            // refill to handle some weird edge case where we have
923
0
                            // less bits than needed for reading the lit-len
924
0
                        }
925
0
                        saved_bitbuf = self.stream.buffer;
926
0
927
0
                        self.stream.drop_bits((entry & 0xFF) as u8);
928
0
929
0
                        let mask = (1 << entry as u8) - 1;
930
0
931
0
                        offset = (entry >> 16) as usize;
932
0
                        offset += (saved_bitbuf & mask) as usize >> (((entry >> 8) & 0xFF) as u8);
933
0
934
0
                        if offset > dest_offset
935
                        {
936
0
                            out_block.truncate(dest_offset);
937
0
938
0
                            let err_msg = DecodeErrorStatus::CorruptData;
939
0
                            let error = InflateDecodeErrors::new(err_msg, out_block);
940
0
941
0
                            return Err(error);
942
0
                        }
943
0
944
0
                        src_offset = dest_offset - offset;
945
0
946
0
                        if self.stream.bits_left < 11
947
0
                        {
948
0
                            self.stream.refill_inner_loop();
949
0
                        }
950
                        // Copy some bytes unconditionally
951
                        // This makes us copy smaller match lengths quicker because we don't need
952
                        // a loop + don't send too much pressure to the Memory unit.
953
0
                        fixed_copy_within::<FASTCOPY_BYTES>(
954
0
                            &mut out_block,
955
0
                            src_offset,
956
0
                            dest_offset
957
0
                        );
958
0
959
0
                        entry = litlen_decode_table[self.stream.peek_bits::<LITLEN_DECODE_BITS>()];
960
0
961
0
                        let mut current_position = dest_offset;
962
0
963
0
                        dest_offset += length;
964
0
965
0
                        if offset == 1
966
0
                        {
967
0
                            // RLE fill with a single byte
968
0
                            let byte_to_repeat = out_block[src_offset];
969
0
                            out_block[current_position..dest_offset].fill(byte_to_repeat);
970
0
                        }
971
0
                        else if offset <= FASTCOPY_BYTES
972
0
                            && current_position + offset < dest_offset
973
                        {
974
                            // The second conditional ensures we only come
975
                            // here if the first copy didn't succeed to copy just enough bytes for a rep
976
                            // match to be valid, i.e we want this path to be taken the least amount
977
                            // of times possible
978
979
                            // the unconditional copy above copied some bytes
980
                            // don't let it go into waste
981
                            // Increment the position we are in by the number of correct bytes
982
                            // currently copied
983
0
                            let mut src_position = src_offset + offset;
984
0
                            let mut dest_position = current_position + offset;
985
986
                            // loop copying offset bytes in place
987
                            // notice this loop does fixed copies but increments in offset bytes :)
988
                            // that is intentional.
989
                            loop
990
                            {
991
0
                                fixed_copy_within::<FASTCOPY_BYTES>(
992
0
                                    &mut out_block,
993
0
                                    src_position,
994
0
                                    dest_position
995
0
                                );
996
0
997
0
                                src_position += offset;
998
0
                                dest_position += offset;
999
0
1000
0
                                if dest_position > dest_offset
1001
                                {
1002
0
                                    break;
1003
0
                                }
1004
                            }
1005
                        }
1006
0
                        else if length > FASTCOPY_BYTES
1007
                        {
1008
0
                            current_position += FASTCOPY_BYTES;
1009
0
                            // fast non-overlapping copy
1010
0
                            //
1011
0
                            // We have enough space to write the ML+FAST_COPY bytes ahead
1012
0
                            // so we know this won't come to shoot us in the foot.
1013
0
                            //
1014
0
                            // An optimization is to copy FAST_COPY_BITS per invocation
1015
0
                            // Currently FASTCOPY_BYTES is 16, this fits in nicely as we
1016
0
                            // it's a single SIMD instruction on a lot of things, i.e x86,Arm and even
1017
0
                            // wasm.
1018
0
1019
0
                            // current position of the match
1020
0
                            let mut dest_src_offset = src_offset + FASTCOPY_BYTES;
1021
1022
                            // Number of bytes we are to copy
1023
                            // copy in batches of FAST_BYTES
1024
                            'match_lengths: loop
1025
                            {
1026
                                // Safety: We resized out_block hence we know it can handle
1027
                                // sloppy copies without it being out of bounds
1028
                                //
1029
                                // Reason: This is a latency critical loop, even branches start
1030
                                // to matter
1031
0
                                fixed_copy_within::<FASTCOPY_BYTES>(
1032
0
                                    &mut out_block,
1033
0
                                    dest_src_offset,
1034
0
                                    current_position
1035
0
                                );
1036
0
1037
0
                                dest_src_offset += FASTCOPY_BYTES;
1038
0
                                current_position += FASTCOPY_BYTES;
1039
0
1040
0
                                if current_position > dest_offset
1041
                                {
1042
0
                                    break 'match_lengths;
1043
0
                                }
1044
                            }
1045
0
                        }
1046
1047
0
                        if dest_offset > self.options.limit
1048
                        {
1049
0
                            out_block.truncate(dest_offset);
1050
0
1051
0
                            let err_msg = DecodeErrorStatus::OutputLimitExceeded(
1052
0
                                self.options.limit,
1053
0
                                dest_offset
1054
0
                            );
1055
0
                            let error = InflateDecodeErrors::new(err_msg, out_block);
1056
0
1057
0
                            return Err(error);
1058
0
                        }
1059
0
1060
0
                        if self.stream.src.len() < self.stream.position + 8
1061
                        {
1062
                            // close to input end, move to the slower one
1063
0
                            break 'sequence;
1064
0
                        }
1065
                    }
1066
0
                }
1067
                // generic loop that does things a bit slower but it's okay since it doesn't
1068
                // deal with a lot of things
1069
                // We can afford to be more careful here, checking that we do
1070
                // not drop non-existent bits etc etc as we do not have the
1071
                // assurances of the fast loop bits above.
1072
                loop
1073
                {
1074
0
                    self.stream.refill();
1075
0
1076
0
                    if self.stream.over_read > usize::from(self.stream.bits_left >> 3)
1077
                    {
1078
0
                        out_block.truncate(dest_offset);
1079
0
1080
0
                        let err_msg = DecodeErrorStatus::CorruptData;
1081
0
                        let error = InflateDecodeErrors::new(err_msg, out_block);
1082
0
1083
0
                        return Err(error);
1084
0
                    }
1085
0
1086
0
                    let literal_mask = self.stream.peek_bits::<LITLEN_DECODE_BITS>();
1087
0
1088
0
                    entry = litlen_decode_table[literal_mask];
1089
0
1090
0
                    saved_bitbuf = self.stream.buffer;
1091
0
1092
0
                    self.stream.drop_bits((entry & 0xFF) as u8);
1093
0
1094
0
                    if (entry & HUFFDEC_SUITABLE_POINTER) != 0
1095
0
                    {
1096
0
                        let extra = self.stream.peek_var_bits(((entry >> 8) & 0x3F) as usize);
1097
0
1098
0
                        entry = litlen_decode_table[(entry >> 16) as usize + extra];
1099
0
                        saved_bitbuf = self.stream.buffer;
1100
0
1101
0
                        self.stream.drop_bits((entry & 0xFF) as u8);
1102
0
                    }
1103
1104
0
                    length = (entry >> 16) as usize;
1105
0
1106
0
                    if (entry & HUFFDEC_LITERAL) != 0
1107
                    {
1108
0
                        resize_and_push(&mut out_block, dest_offset, length as u8);
1109
0
1110
0
                        dest_offset += 1;
1111
0
1112
0
                        continue;
1113
0
                    }
1114
0
1115
0
                    if (entry & HUFFDEC_END_OF_BLOCK) != 0
1116
                    {
1117
0
                        break 'decode;
1118
0
                    }
1119
0
1120
0
                    let mask = (1 << entry as u8) - 1;
1121
0
1122
0
                    length += (saved_bitbuf & mask) as usize >> ((entry >> 8) as u8);
1123
0
1124
0
                    self.stream.refill();
1125
0
1126
0
                    entry = offset_decode_table[self.stream.peek_bits::<OFFSET_TABLEBITS>()];
1127
0
1128
0
                    if (entry & HUFFDEC_EXCEPTIONAL) != 0
1129
0
                    {
1130
0
                        // offset requires a subtable
1131
0
                        self.stream.drop_bits(OFFSET_TABLEBITS as u8);
1132
0
1133
0
                        let extra = self.stream.peek_var_bits(((entry >> 8) & 0x3F) as usize);
1134
0
1135
0
                        entry = offset_decode_table[((entry >> 16) as usize + extra) & 511];
1136
0
                    }
1137
1138
                    // ensure there is enough space for a fast copy
1139
0
                    if dest_offset + length + FASTCOPY_BYTES > out_block.len()
1140
0
                    {
1141
0
                        let new_len = out_block.len() + RESIZE_BY + length;
1142
0
                        out_block.resize(new_len, 0);
1143
0
                    }
1144
0
                    saved_bitbuf = self.stream.buffer;
1145
0
1146
0
                    let mask = (1 << (entry & 0xFF) as u8) - 1;
1147
0
1148
0
                    offset = (entry >> 16) as usize;
1149
0
                    offset += (saved_bitbuf & mask) as usize >> ((entry >> 8) as u8);
1150
0
1151
0
                    if offset > dest_offset
1152
                    {
1153
0
                        out_block.truncate(dest_offset);
1154
0
1155
0
                        let err_msg = DecodeErrorStatus::CorruptData;
1156
0
                        let error = InflateDecodeErrors::new(err_msg, out_block);
1157
0
1158
0
                        return Err(error);
1159
0
                    }
1160
0
1161
0
                    src_offset = dest_offset - offset;
1162
0
1163
0
                    self.stream.drop_bits(entry as u8);
1164
0
1165
0
                    let (dest_src, dest_ptr) = out_block.split_at_mut(dest_offset);
1166
0
1167
0
                    if src_offset + length + FASTCOPY_BYTES > dest_offset
1168
0
                    {
1169
0
                        // overlapping copy
1170
0
                        // do a simple rep match
1171
0
                        copy_rep_matches(&mut out_block, src_offset, dest_offset, length);
1172
0
                    }
1173
                    else
1174
0
                    {
1175
0
                        dest_ptr[0..length]
1176
0
                            .copy_from_slice(&dest_src[src_offset..src_offset + length]);
1177
0
                    }
1178
1179
0
                    dest_offset += length;
1180
0
1181
0
                    if dest_offset > self.options.limit
1182
                    {
1183
0
                        out_block.truncate(dest_offset);
1184
0
1185
0
                        let err_msg =
1186
0
                            DecodeErrorStatus::OutputLimitExceeded(self.options.limit, dest_offset);
1187
0
                        let error = InflateDecodeErrors::new(err_msg, out_block);
1188
0
1189
0
                        return Err(error);
1190
0
                    }
1191
                }
1192
            }
1193
            /*
1194
             * If any of the implicit appended zero bytes were consumed (not just
1195
             * refilled) before hitting end of stream, then the data is bad.
1196
             */
1197
0
            if self.stream.over_read > usize::from(self.stream.bits_left >> 3)
1198
            {
1199
0
                out_block.truncate(dest_offset);
1200
0
1201
0
                let err_msg = DecodeErrorStatus::CorruptData;
1202
0
                let error = InflateDecodeErrors::new(err_msg, out_block);
1203
0
1204
0
                return Err(error);
1205
0
            }
1206
0
1207
0
            if self.is_last_block
1208
            {
1209
0
                break;
1210
0
            }
1211
        }
1212
1213
        // decompression. DONE
1214
        // Truncate data to match the number of actual
1215
        // bytes written.
1216
0
        out_block.truncate(dest_offset);
1217
0
1218
0
        Ok(out_block)
1219
0
    }
1220
1221
    /// Build decode tables for static and dynamic
1222
    /// huffman blocks.
1223
0
    fn build_decode_table(&mut self, block_type: u64) -> Result<(), DecodeErrorStatus>
1224
0
    {
1225
        const COUNT: usize =
1226
            DEFLATE_NUM_LITLEN_SYMS + DEFLATE_NUM_OFFSET_SYMS + DELFATE_MAX_LENS_OVERRUN;
1227
1228
0
        let mut lens = [0_u8; COUNT];
1229
0
        let mut precode_lens = [0; DEFLATE_NUM_PRECODE_SYMS];
1230
0
        let mut precode_decode_table = [0_u32; PRECODE_ENOUGH];
1231
0
        let mut litlen_decode_table = [0_u32; LITLEN_ENOUGH];
1232
0
        let mut offset_decode_table = [0; OFFSET_ENOUGH];
1233
0
1234
0
        let mut num_litlen_syms = 0;
1235
0
        let mut num_offset_syms = 0;
1236
0
1237
0
        if block_type == DEFLATE_BLOCKTYPE_DYNAMIC_HUFFMAN
1238
        {
1239
            const SINGLE_PRECODE: usize = 3;
1240
1241
0
            self.static_codes_loaded = false;
1242
0
1243
0
            // Dynamic Huffman block
1244
0
            // Read codeword lengths
1245
0
            if !self.stream.has(5 + 5 + 4)
1246
            {
1247
0
                return Err(DecodeErrorStatus::InsufficientData);
1248
0
            }
1249
0
1250
0
            num_litlen_syms = 257 + (self.stream.get_bits(5)) as usize;
1251
0
            num_offset_syms = 1 + (self.stream.get_bits(5)) as usize;
1252
0
1253
0
            let num_explicit_precode_lens = 4 + (self.stream.get_bits(4)) as usize;
1254
0
1255
0
            self.stream.refill();
1256
0
1257
0
            if !self.stream.has(3)
1258
            {
1259
0
                return Err(DecodeErrorStatus::InsufficientData);
1260
0
            }
1261
0
1262
0
            let first_precode = self.stream.get_bits(3) as u8;
1263
0
            let expected = (SINGLE_PRECODE * num_explicit_precode_lens.saturating_sub(1)) as u8;
1264
0
1265
0
            precode_lens[usize::from(DEFLATE_PRECODE_LENS_PERMUTATION[0])] = first_precode;
1266
0
1267
0
            self.stream.refill();
1268
0
1269
0
            if !self.stream.has(expected)
1270
            {
1271
0
                return Err(DecodeErrorStatus::InsufficientData);
1272
0
            }
1273
1274
0
            for i in DEFLATE_PRECODE_LENS_PERMUTATION[1..]
1275
0
                .iter()
1276
0
                .take(num_explicit_precode_lens - 1)
1277
0
            {
1278
0
                let bits = self.stream.get_bits(3) as u8;
1279
0
1280
0
                precode_lens[usize::from(*i)] = bits;
1281
0
            }
1282
1283
0
            self.build_decode_table_inner(
1284
0
                &precode_lens,
1285
0
                &PRECODE_DECODE_RESULTS,
1286
0
                &mut precode_decode_table,
1287
0
                PRECODE_TABLE_BITS,
1288
0
                DEFLATE_NUM_PRECODE_SYMS,
1289
0
                DEFLATE_MAX_CODEWORD_LENGTH
1290
0
            )?;
1291
1292
            /* Decode the litlen and offset codeword lengths. */
1293
1294
0
            let mut i = 0;
1295
1296
            loop
1297
            {
1298
0
                if i >= num_litlen_syms + num_offset_syms
1299
                {
1300
                    // confirm here since with a continue loop stuff
1301
                    // breaks
1302
0
                    break;
1303
0
                }
1304
0
1305
0
                let rep_val: u8;
1306
0
                let rep_count: u64;
1307
0
1308
0
                if !self.stream.has(DEFLATE_MAX_PRE_CODEWORD_LEN + 7)
1309
0
                {
1310
0
                    self.stream.refill();
1311
0
                }
1312
                // decode next pre-code symbol
1313
0
                let entry_pos = self
1314
0
                    .stream
1315
0
                    .peek_bits::<{ DEFLATE_MAX_PRE_CODEWORD_LEN as usize }>();
1316
0
1317
0
                let entry = precode_decode_table[entry_pos];
1318
0
                let presym = entry >> 16;
1319
0
1320
0
                if !self.stream.has(entry as u8)
1321
                {
1322
0
                    return Err(DecodeErrorStatus::InsufficientData);
1323
0
                }
1324
0
1325
0
                self.stream.drop_bits(entry as u8);
1326
0
1327
0
                if presym < 16
1328
                {
1329
                    // explicit codeword length
1330
0
                    lens[i] = presym as u8;
1331
0
                    i += 1;
1332
0
                    continue;
1333
0
                }
1334
0
1335
0
                /* Run-length encoded codeword lengths */
1336
0
1337
0
                /*
1338
0
                 * Note: we don't need verify that the repeat count
1339
0
                 * doesn't overflow the number of elements, since we've
1340
0
                 * sized the lens array to have enough extra space to
1341
0
                 * allow for the worst-case overrun (138 zeroes when
1342
0
                 * only 1 length was remaining).
1343
0
                 *
1344
0
                 * In the case of the small repeat counts (presyms 16
1345
0
                 * and 17), it is fastest to always write the maximum
1346
0
                 * number of entries.  That gets rid of branches that
1347
0
                 * would otherwise be required.
1348
0
                 *
1349
0
                 * It is not just because of the numerical order that
1350
0
                 * our checks go in the order 'presym < 16', 'presym ==
1351
0
                 * 16', and 'presym == 17'.  For typical data this is
1352
0
                 * ordered from most frequent to least frequent case.
1353
0
                 */
1354
0
                if presym == 16
1355
                {
1356
0
                    if i == 0
1357
                    {
1358
0
                        return Err(DecodeErrorStatus::CorruptData);
1359
0
                    }
1360
0
1361
0
                    if !self.stream.has(2)
1362
                    {
1363
0
                        return Err(DecodeErrorStatus::InsufficientData);
1364
0
                    }
1365
0
1366
0
                    // repeat previous length three to 6 times
1367
0
                    rep_val = lens[i - 1];
1368
0
                    rep_count = 3 + self.stream.get_bits(2);
1369
0
                    lens[i..i + 6].fill(rep_val);
1370
0
                    i += rep_count as usize;
1371
                }
1372
0
                else if presym == 17
1373
                {
1374
0
                    if !self.stream.has(3)
1375
                    {
1376
0
                        return Err(DecodeErrorStatus::InsufficientData);
1377
0
                    }
1378
0
                    /* Repeat zero 3 - 10 times. */
1379
0
                    rep_count = 3 + self.stream.get_bits(3);
1380
0
                    lens[i..i + 10].fill(0);
1381
0
                    i += rep_count as usize;
1382
                }
1383
                else
1384
                {
1385
0
                    if !self.stream.has(7)
1386
                    {
1387
0
                        return Err(DecodeErrorStatus::InsufficientData);
1388
0
                    }
1389
0
                    // repeat zero 11-138 times.
1390
0
                    rep_count = 11 + self.stream.get_bits(7);
1391
0
                    lens[i..i + rep_count as usize].fill(0);
1392
0
                    i += rep_count as usize;
1393
                }
1394
1395
0
                if i >= num_litlen_syms + num_offset_syms
1396
                {
1397
0
                    break;
1398
0
                }
1399
            }
1400
        }
1401
0
        else if block_type == DEFLATE_BLOCKTYPE_STATIC
1402
        {
1403
0
            if self.static_codes_loaded
1404
            {
1405
0
                return Ok(());
1406
0
            }
1407
0
1408
0
            self.static_codes_loaded = true;
1409
0
1410
0
            lens[000..144].fill(8);
1411
0
            lens[144..256].fill(9);
1412
0
            lens[256..280].fill(7);
1413
0
            lens[280..288].fill(8);
1414
0
            lens[288..].fill(5);
1415
0
1416
0
            num_litlen_syms = 288;
1417
0
            num_offset_syms = 32;
1418
0
        }
1419
        // build offset decode table
1420
0
        self.build_decode_table_inner(
1421
0
            &lens[num_litlen_syms..],
1422
0
            &OFFSET_DECODE_RESULTS,
1423
0
            &mut offset_decode_table,
1424
0
            OFFSET_TABLEBITS,
1425
0
            num_offset_syms,
1426
0
            DEFLATE_MAX_OFFSET_CODEWORD_LENGTH
1427
0
        )?;
1428
1429
0
        self.build_decode_table_inner(
1430
0
            &lens,
1431
0
            &LITLEN_DECODE_RESULTS,
1432
0
            &mut litlen_decode_table,
1433
0
            LITLEN_TABLE_BITS,
1434
0
            num_litlen_syms,
1435
0
            DEFLATE_MAX_LITLEN_CODEWORD_LENGTH
1436
0
        )?;
1437
1438
0
        self.deflate_header_tables.offset_decode_table = offset_decode_table;
1439
0
        self.deflate_header_tables.litlen_decode_table = litlen_decode_table;
1440
0
1441
0
        Ok(())
1442
0
    }
1443
    /// Build the decode table for the precode
1444
    #[allow(clippy::needless_range_loop)]
1445
0
    fn build_decode_table_inner(
1446
0
        &mut self, lens: &[u8], decode_results: &[u32], decode_table: &mut [u32],
1447
0
        table_bits: usize, num_syms: usize, mut max_codeword_len: usize
1448
0
    ) -> Result<(), DecodeErrorStatus>
1449
0
    {
1450
        const BITS: u32 = usize::BITS - 1;
1451
1452
0
        let mut len_counts: [u32; DEFLATE_MAX_CODEWORD_LENGTH + 1] =
1453
0
            [0; DEFLATE_MAX_CODEWORD_LENGTH + 1];
1454
0
        let mut offsets: [u32; DEFLATE_MAX_CODEWORD_LENGTH + 1] =
1455
0
            [0; DEFLATE_MAX_CODEWORD_LENGTH + 1];
1456
0
        let mut sorted_syms: [u16; DEFLATE_MAX_NUM_SYMS] = [0; DEFLATE_MAX_NUM_SYMS];
1457
1458
        let mut i;
1459
1460
        // count how many codewords have each length, including 0.
1461
0
        for sym in 0..num_syms
1462
0
        {
1463
0
            len_counts[usize::from(lens[sym])] += 1;
1464
0
        }
1465
1466
        /*
1467
         * Determine the actual maximum codeword length that was used, and
1468
         * decrease table_bits to it if allowed.
1469
         */
1470
0
        while max_codeword_len > 1 && len_counts[max_codeword_len] == 0
1471
0
        {
1472
0
            max_codeword_len -= 1;
1473
0
        }
1474
        /*
1475
         * Sort the symbols primarily by increasing codeword length and
1476
         *  A temporary array of length @num_syms.
1477
         * secondarily by increasing symbol value; or equivalently by their
1478
         * codewords in lexicographic order, since a canonical code is assumed.
1479
         *
1480
         * For efficiency, also compute 'codespace_used' in the same pass over
1481
         * 'len_counts[]' used to build 'offsets[]' for sorting.
1482
         */
1483
0
        offsets[0] = 0;
1484
0
        offsets[1] = len_counts[0];
1485
0
1486
0
        let mut codespace_used = 0_u32;
1487
1488
0
        for len in 1..max_codeword_len
1489
0
        {
1490
0
            offsets[len + 1] = offsets[len] + len_counts[len];
1491
0
            codespace_used = (codespace_used << 1) + len_counts[len];
1492
0
        }
1493
0
        codespace_used = (codespace_used << 1) + len_counts[max_codeword_len];
1494
1495
0
        for sym in 0..num_syms
1496
0
        {
1497
0
            let pos = usize::from(lens[sym]);
1498
0
            sorted_syms[offsets[pos] as usize] = sym as u16;
1499
0
            offsets[pos] += 1;
1500
0
        }
1501
0
        i = (offsets[0]) as usize;
1502
0
1503
0
        /*
1504
0
         * Check whether the lengths form a complete code (exactly fills the
1505
0
         * codespace), an incomplete code (doesn't fill the codespace), or an
1506
0
         * overfull code (overflows the codespace).  A codeword of length 'n'
1507
0
         * uses proportion '1/(2^n)' of the codespace.  An overfull code is
1508
0
         * nonsensical, so is considered invalid.  An incomplete code is
1509
0
         * considered valid only in two specific cases; see below.
1510
0
         */
1511
0
1512
0
        // Overfull code
1513
0
        if codespace_used > 1 << max_codeword_len
1514
        {
1515
0
            return Err(DecodeErrorStatus::Generic("Overflown code"));
1516
0
        }
1517
0
        // incomplete code
1518
0
        if codespace_used < 1 << max_codeword_len
1519
        {
1520
0
            let entry = if codespace_used == 0
1521
            {
1522
                /*
1523
                 * An empty code is allowed.  This can happen for the
1524
                 * offset code in DEFLATE, since a dynamic Huffman block
1525
                 * need not contain any matches.
1526
                 */
1527
1528
                /* sym=0, len=1 (arbitrary) */
1529
0
                make_decode_table_entry(decode_results, 0, 1)
1530
            }
1531
            else
1532
            {
1533
                /*
1534
                 * Allow codes with a single used symbol, with codeword
1535
                 * length 1.  The DEFLATE RFC is unclear regarding this
1536
                 * case.  What zlib's decompressor does is permit this
1537
                 * for the litlen and offset codes and assume the
1538
                 * codeword is '0' rather than '1'.  We do the same
1539
                 * except we allow this for precodes too, since there's
1540
                 * no convincing reason to treat the codes differently.
1541
                 * We also assign both codewords '0' and '1' to the
1542
                 * symbol to avoid having to handle '1' specially.
1543
                 */
1544
0
                if codespace_used != 1 << (max_codeword_len - 1) || len_counts[1] != 1
1545
                {
1546
0
                    return Err(DecodeErrorStatus::Generic(
1547
0
                        "Cannot work with empty pre-code table"
1548
0
                    ));
1549
0
                }
1550
0
                make_decode_table_entry(decode_results, usize::from(sorted_syms[i]), 1)
1551
            };
1552
            /*
1553
             * Note: the decode table still must be fully initialized, in
1554
             * case the stream is malformed and contains bits from the part
1555
             * of the codespace the incomplete code doesn't use.
1556
             */
1557
0
            decode_table.fill(entry);
1558
0
            return Ok(());
1559
0
        }
1560
0
1561
0
        /*
1562
0
         * The lengths form a complete code.  Now, enumerate the codewords in
1563
0
         * lexicographic order and fill the decode table entries for each one.
1564
0
         *
1565
0
         * First, process all codewords with len <= table_bits.  Each one gets
1566
0
         * '2^(table_bits-len)' direct entries in the table.
1567
0
         *
1568
0
         * Since DEFLATE uses bit-reversed codewords, these entries aren't
1569
0
         * consecutive but rather are spaced '2^len' entries apart.  This makes
1570
0
         * filling them naively somewhat awkward and inefficient, since strided
1571
0
         * stores are less cache-friendly and preclude the use of word or
1572
0
         * vector-at-a-time stores to fill multiple entries per instruction.
1573
0
         *
1574
0
         * To optimize this, we incrementally double the table size.  When
1575
0
         * processing codewords with length 'len', the table is treated as
1576
0
         * having only '2^len' entries, so each codeword uses just one entry.
1577
0
         * Then, each time 'len' is incremented, the table size is doubled and
1578
0
         * the first half is copied to the second half.  This significantly
1579
0
         * improves performance over naively doing strided stores.
1580
0
         *
1581
0
         * Note that some entries copied for each table doubling may not have
1582
0
         * been initialized yet, but it doesn't matter since they're guaranteed
1583
0
         * to be initialized later (because the Huffman code is complete).
1584
0
         */
1585
0
        let mut codeword = 0;
1586
0
        let mut len = 1;
1587
0
        let mut count = len_counts[1];
1588
1589
0
        while count == 0
1590
        {
1591
0
            len += 1;
1592
0
1593
0
            if len >= len_counts.len()
1594
            {
1595
0
                break;
1596
0
            }
1597
0
            count = len_counts[len];
1598
        }
1599
1600
0
        let mut curr_table_end = 1 << len;
1601
1602
0
        while len <= table_bits
1603
        {
1604
            // Process all count codewords with length len
1605
            loop
1606
            {
1607
0
                let entry = make_decode_table_entry(
1608
0
                    decode_results,
1609
0
                    usize::from(sorted_syms[i]),
1610
0
                    len as u32
1611
0
                );
1612
0
                i += 1;
1613
0
                // fill first entry for current codeword
1614
0
                decode_table[codeword] = entry;
1615
0
1616
0
                if codeword == curr_table_end - 1
1617
                {
1618
                    // last codeword (all 1's)
1619
0
                    for _ in len..table_bits
1620
0
                    {
1621
0
                        decode_table.copy_within(0..curr_table_end, curr_table_end);
1622
0
1623
0
                        curr_table_end <<= 1;
1624
0
                    }
1625
0
                    return Ok(());
1626
0
                }
1627
0
                /*
1628
0
                 * To advance to the lexicographically next codeword in
1629
0
                 * the canonical code, the codeword must be incremented,
1630
0
                 * then 0's must be appended to the codeword as needed
1631
0
                 * to match the next codeword's length.
1632
0
                 *
1633
0
                 * Since the codeword is bit-reversed, appending 0's is
1634
0
                 * a no-op.  However, incrementing it is nontrivial.  To
1635
0
                 * do so efficiently, use the 'bsr' instruction to find
1636
0
                 * the last (highest order) 0 bit in the codeword, set
1637
0
                 * it, and clear any later (higher order) 1 bits.  But
1638
0
                 * 'bsr' actually finds the highest order 1 bit, so to
1639
0
                 * use it first flip all bits in the codeword by XOR' ing
1640
0
                 * it with (1U << len) - 1 == cur_table_end - 1.
1641
0
                 */
1642
0
1643
0
                let adv = BITS - (codeword ^ (curr_table_end - 1)).leading_zeros();
1644
0
                let bit = 1 << adv;
1645
0
1646
0
                codeword &= bit - 1;
1647
0
                codeword |= bit;
1648
0
                count -= 1;
1649
0
1650
0
                if count == 0
1651
                {
1652
0
                    break;
1653
0
                }
1654
            }
1655
            // advance to the next codeword length
1656
            loop
1657
            {
1658
0
                len += 1;
1659
0
1660
0
                if len <= table_bits
1661
0
                {
1662
0
                    // dest is decode_table[curr_table_end]
1663
0
                    // source is decode_table(start of table);
1664
0
                    // size is curr_table;
1665
0
1666
0
                    decode_table.copy_within(0..curr_table_end, curr_table_end);
1667
0
1668
0
                    //decode_table.copy_within(range, curr_table_end);
1669
0
                    curr_table_end <<= 1;
1670
0
                }
1671
0
                count = len_counts[len];
1672
0
1673
0
                if count != 0
1674
                {
1675
0
                    break;
1676
0
                }
1677
            }
1678
        }
1679
        // process codewords with len > table_bits.
1680
        // Require sub-tables
1681
0
        curr_table_end = 1 << table_bits;
1682
0
1683
0
        let mut subtable_prefix = usize::MAX;
1684
0
        let mut subtable_start = 0;
1685
        let mut subtable_bits;
1686
1687
        loop
1688
        {
1689
            /*
1690
             * Start a new sub-table if the first 'table_bits' bits of the
1691
             * codeword don't match the prefix of the current subtable.
1692
             */
1693
0
            if codeword & ((1_usize << table_bits) - 1) != subtable_prefix
1694
            {
1695
0
                subtable_prefix = codeword & ((1 << table_bits) - 1);
1696
0
                subtable_start = curr_table_end;
1697
0
1698
0
                /*
1699
0
                 * Calculate the subtable length.  If the codeword has
1700
0
                 * length 'table_bits + n', then the subtable needs
1701
0
                 * '2^n' entries.  But it may need more; if fewer than
1702
0
                 * '2^n' codewords of length 'table_bits + n' remain,
1703
0
                 * then the length will need to be incremented to bring
1704
0
                 * in longer codewords until the subtable can be
1705
0
                 * completely filled.  Note that because the Huffman
1706
0
                 * code is complete, it will always be possible to fill
1707
0
                 * the sub-table eventually.
1708
0
                 */
1709
0
                subtable_bits = len - table_bits;
1710
0
                codespace_used = count;
1711
1712
0
                while codespace_used < (1 << subtable_bits)
1713
                {
1714
0
                    subtable_bits += 1;
1715
0
1716
0
                    if subtable_bits + table_bits > 15
1717
                    {
1718
0
                        return Err(DecodeErrorStatus::CorruptData);
1719
0
                    }
1720
0
1721
0
                    codespace_used = (codespace_used << 1) + len_counts[table_bits + subtable_bits];
1722
                }
1723
1724
                /*
1725
                 * Create the entry that points from the main table to
1726
                 * the subtable.
1727
                 */
1728
0
                decode_table[subtable_prefix] = (subtable_start as u32) << 16
1729
0
                    | HUFFDEC_EXCEPTIONAL
1730
0
                    | HUFFDEC_SUITABLE_POINTER
1731
0
                    | (subtable_bits as u32) << 8
1732
0
                    | table_bits as u32;
1733
0
1734
0
                curr_table_end = subtable_start + (1 << subtable_bits);
1735
0
            }
1736
1737
            /* Fill the sub-table entries for the current codeword. */
1738
1739
0
            let stride = 1 << (len - table_bits);
1740
0
1741
0
            let mut j = subtable_start + (codeword >> table_bits);
1742
0
1743
0
            let entry = make_decode_table_entry(
1744
0
                decode_results,
1745
0
                sorted_syms[i] as usize,
1746
0
                (len - table_bits) as u32
1747
0
            );
1748
0
            i += 1;
1749
1750
0
            while j < curr_table_end
1751
0
            {
1752
0
                decode_table[j] = entry;
1753
0
                j += stride;
1754
0
            }
1755
            //advance to the next codeword
1756
0
            if codeword == (1 << len) - 1
1757
            {
1758
                // last codeword
1759
0
                return Ok(());
1760
0
            }
1761
0
1762
0
            let adv = BITS - (codeword ^ ((1 << len) - 1)).leading_zeros();
1763
0
            let bit = 1 << adv;
1764
0
1765
0
            codeword &= bit - 1;
1766
0
            codeword |= bit;
1767
0
            count -= 1;
1768
1769
0
            while count == 0
1770
0
            {
1771
0
                len += 1;
1772
0
                count = len_counts[len];
1773
0
            }
1774
        }
1775
0
    }
1776
}
1777
1778
const RESIZE_BY: usize = 1024 * 4; // 4 kb
1779
1780
/// Resize vector if its current space wont
1781
/// be able to store a new byte and then push an element to that new space
1782
#[inline(always)]
1783
0
fn resize_and_push(buf: &mut Vec<u8>, position: usize, elm: u8)
1784
0
{
1785
0
    if buf.len() <= position
1786
0
    {
1787
0
        let new_len = buf.len() + RESIZE_BY;
1788
0
        buf.resize(new_len, 0);
1789
0
    }
1790
0
    buf[position] = elm;
1791
0
}