Coverage Report

Created: 2026-01-16 07:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/lzma-rs-0.2.0/src/decode/lzma.rs
Line
Count
Source
1
use crate::decode::lzbuffer;
2
use crate::decode::rangecoder;
3
use crate::error;
4
use byteorder::{LittleEndian, ReadBytesExt};
5
use std::io;
6
use std::marker::PhantomData;
7
8
use crate::decompress::Options;
9
use crate::decompress::UnpackedSize;
10
11
/// Maximum input data that can be processed in one iteration.
12
/// Libhtp uses the following equation to define the maximum number of bits
13
/// for the worst case scenario:
14
///   log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160
15
const MAX_REQUIRED_INPUT: usize = 20;
16
17
/// Processing mode for decompression.
18
///
19
/// Tells the decompressor if we should expect more data after parsing the
20
/// current input.
21
#[derive(Debug, PartialEq)]
22
enum ProcessingMode {
23
    /// Streaming mode. Process the input bytes but assume there will be more
24
    /// chunks of input data to receive in future calls to `process_mode()`.
25
    Partial,
26
    /// Synchronous mode. Process the input bytes and confirm end of stream has been reached.
27
    /// Use this mode if you are processing a fixed buffer of compressed data, or after
28
    /// using `Mode::Partial` to check for the end of stream.
29
    Finish,
30
}
31
32
/// Result of the next iteration of processing.
33
///
34
/// Indicates whether processing should continue or is finished.
35
#[derive(Debug, PartialEq)]
36
enum ProcessingStatus {
37
    Continue,
38
    Finished,
39
}
40
41
pub struct LzmaParams {
42
    // most lc significant bits of previous byte are part of the literal context
43
    lc: u32, // 0..8
44
    lp: u32, // 0..4
45
    // context for literal/match is plaintext offset modulo 2^pb
46
    pb: u32, // 0..4
47
    dict_size: u32,
48
    unpacked_size: Option<u64>,
49
}
50
51
impl LzmaParams {
52
123k
    pub fn read_header<R>(input: &mut R, options: &Options) -> error::Result<LzmaParams>
53
123k
    where
54
123k
        R: io::BufRead,
55
    {
56
        // Properties
57
123k
        let props = input.read_u8().map_err(error::Error::HeaderTooShort)?;
58
59
123k
        let mut pb = props as u32;
60
123k
        if pb >= 225 {
61
10.5k
            return Err(error::Error::LzmaError(format!(
62
10.5k
                "LZMA header invalid properties: {} must be < 225",
63
10.5k
                pb
64
10.5k
            )));
65
113k
        }
66
67
113k
        let lc: u32 = pb % 9;
68
113k
        pb /= 9;
69
113k
        let lp: u32 = pb % 5;
70
113k
        pb /= 5;
71
72
        lzma_info!("Properties {{ lc: {}, lp: {}, pb: {} }}", lc, lp, pb);
73
74
        // Dictionary
75
113k
        let dict_size_provided = input
76
113k
            .read_u32::<LittleEndian>()
77
113k
            .map_err(error::Error::HeaderTooShort)?;
78
94.9k
        let dict_size = if dict_size_provided < 0x1000 {
79
5.14k
            0x1000
80
        } else {
81
89.8k
            dict_size_provided
82
        };
83
84
        lzma_info!("Dict size: {}", dict_size);
85
86
        // Unpacked size
87
94.9k
        let unpacked_size: Option<u64> = match options.unpacked_size {
88
            UnpackedSize::ReadFromHeader => {
89
94.9k
                let unpacked_size_provided = input
90
94.9k
                    .read_u64::<LittleEndian>()
91
94.9k
                    .map_err(error::Error::HeaderTooShort)?;
92
69.0k
                let marker_mandatory: bool = unpacked_size_provided == 0xFFFF_FFFF_FFFF_FFFF;
93
69.0k
                if marker_mandatory {
94
318
                    None
95
                } else {
96
68.7k
                    Some(unpacked_size_provided)
97
                }
98
            }
99
0
            UnpackedSize::ReadHeaderButUseProvided(x) => {
100
0
                input
101
0
                    .read_u64::<LittleEndian>()
102
0
                    .map_err(error::Error::HeaderTooShort)?;
103
0
                x
104
            }
105
0
            UnpackedSize::UseProvided(x) => x,
106
        };
107
108
        lzma_info!("Unpacked size: {:?}", unpacked_size);
109
110
69.0k
        let params = LzmaParams {
111
69.0k
            lc,
112
69.0k
            lp,
113
69.0k
            pb,
114
69.0k
            dict_size,
115
69.0k
            unpacked_size,
116
69.0k
        };
117
118
69.0k
        Ok(params)
119
123k
    }
Unexecuted instantiation: <lzma_rs::decode::lzma::LzmaParams>::read_header::<&mut std::io::cursor::Cursor<&[u8]>>
<lzma_rs::decode::lzma::LzmaParams>::read_header::<&mut std::io::cursor::Cursor<&[u8]>>
Line
Count
Source
52
123k
    pub fn read_header<R>(input: &mut R, options: &Options) -> error::Result<LzmaParams>
53
123k
    where
54
123k
        R: io::BufRead,
55
    {
56
        // Properties
57
123k
        let props = input.read_u8().map_err(error::Error::HeaderTooShort)?;
58
59
123k
        let mut pb = props as u32;
60
123k
        if pb >= 225 {
61
10.5k
            return Err(error::Error::LzmaError(format!(
62
10.5k
                "LZMA header invalid properties: {} must be < 225",
63
10.5k
                pb
64
10.5k
            )));
65
113k
        }
66
67
113k
        let lc: u32 = pb % 9;
68
113k
        pb /= 9;
69
113k
        let lp: u32 = pb % 5;
70
113k
        pb /= 5;
71
72
        lzma_info!("Properties {{ lc: {}, lp: {}, pb: {} }}", lc, lp, pb);
73
74
        // Dictionary
75
113k
        let dict_size_provided = input
76
113k
            .read_u32::<LittleEndian>()
77
113k
            .map_err(error::Error::HeaderTooShort)?;
78
94.9k
        let dict_size = if dict_size_provided < 0x1000 {
79
5.14k
            0x1000
80
        } else {
81
89.8k
            dict_size_provided
82
        };
83
84
        lzma_info!("Dict size: {}", dict_size);
85
86
        // Unpacked size
87
94.9k
        let unpacked_size: Option<u64> = match options.unpacked_size {
88
            UnpackedSize::ReadFromHeader => {
89
94.9k
                let unpacked_size_provided = input
90
94.9k
                    .read_u64::<LittleEndian>()
91
94.9k
                    .map_err(error::Error::HeaderTooShort)?;
92
69.0k
                let marker_mandatory: bool = unpacked_size_provided == 0xFFFF_FFFF_FFFF_FFFF;
93
69.0k
                if marker_mandatory {
94
318
                    None
95
                } else {
96
68.7k
                    Some(unpacked_size_provided)
97
                }
98
            }
99
0
            UnpackedSize::ReadHeaderButUseProvided(x) => {
100
0
                input
101
0
                    .read_u64::<LittleEndian>()
102
0
                    .map_err(error::Error::HeaderTooShort)?;
103
0
                x
104
            }
105
0
            UnpackedSize::UseProvided(x) => x,
106
        };
107
108
        lzma_info!("Unpacked size: {:?}", unpacked_size);
109
110
69.0k
        let params = LzmaParams {
111
69.0k
            lc,
112
69.0k
            lp,
113
69.0k
            pb,
114
69.0k
            dict_size,
115
69.0k
            unpacked_size,
116
69.0k
        };
117
118
69.0k
        Ok(params)
119
123k
    }
Unexecuted instantiation: <lzma_rs::decode::lzma::LzmaParams>::read_header::<_>
Unexecuted instantiation: <lzma_rs::decode::lzma::LzmaParams>::read_header::<&mut std::io::cursor::Cursor<&[u8]>>
120
}
121
122
pub struct DecoderState<W, LZB>
123
where
124
    W: io::Write,
125
    LZB: lzbuffer::LzBuffer<W>,
126
{
127
    _phantom: PhantomData<W>,
128
    // Buffer input data here if we need more for decompression. Up to
129
    // MAX_REQUIRED_INPUT bytes can be consumed during one iteration.
130
    partial_input_buf: std::io::Cursor<[u8; MAX_REQUIRED_INPUT]>,
131
    pub output: LZB,
132
    // most lc significant bits of previous byte are part of the literal context
133
    pub lc: u32, // 0..8
134
    pub lp: u32, // 0..4
135
    // context for literal/match is plaintext offset modulo 2^pb
136
    pub pb: u32, // 0..4
137
    unpacked_size: Option<u64>,
138
    literal_probs: Vec<Vec<u16>>,
139
    pos_slot_decoder: Vec<rangecoder::BitTree>,
140
    align_decoder: rangecoder::BitTree,
141
    pos_decoders: [u16; 115],
142
    is_match: [u16; 192], // true = LZ, false = literal
143
    is_rep: [u16; 12],
144
    is_rep_g0: [u16; 12],
145
    is_rep_g1: [u16; 12],
146
    is_rep_g2: [u16; 12],
147
    is_rep_0long: [u16; 192],
148
    state: usize,
149
    rep: [usize; 4],
150
    len_decoder: rangecoder::LenDecoder,
151
    rep_len_decoder: rangecoder::LenDecoder,
152
}
153
154
// Initialize decoder with accumulating buffer
155
0
pub fn new_accum<W>(
156
0
    output: lzbuffer::LzAccumBuffer<W>,
157
0
    lc: u32,
158
0
    lp: u32,
159
0
    pb: u32,
160
0
    unpacked_size: Option<u64>,
161
0
) -> DecoderState<W, lzbuffer::LzAccumBuffer<W>>
162
0
where
163
0
    W: io::Write,
164
{
165
0
    DecoderState {
166
0
        _phantom: PhantomData,
167
0
        partial_input_buf: std::io::Cursor::new([0; MAX_REQUIRED_INPUT]),
168
0
        output,
169
0
        lc,
170
0
        lp,
171
0
        pb,
172
0
        unpacked_size,
173
0
        literal_probs: vec![vec![0x400; 0x300]; 1 << (lc + lp)],
174
0
        pos_slot_decoder: vec![rangecoder::BitTree::new(6); 4],
175
0
        align_decoder: rangecoder::BitTree::new(4),
176
0
        pos_decoders: [0x400; 115],
177
0
        is_match: [0x400; 192],
178
0
        is_rep: [0x400; 12],
179
0
        is_rep_g0: [0x400; 12],
180
0
        is_rep_g1: [0x400; 12],
181
0
        is_rep_g2: [0x400; 12],
182
0
        is_rep_0long: [0x400; 192],
183
0
        state: 0,
184
0
        rep: [0; 4],
185
0
        len_decoder: rangecoder::LenDecoder::new(),
186
0
        rep_len_decoder: rangecoder::LenDecoder::new(),
187
0
    }
188
0
}
189
190
// Initialize decoder with circular buffer
191
0
pub fn new_circular<W>(
192
0
    output: W,
193
0
    params: LzmaParams,
194
0
) -> error::Result<DecoderState<W, lzbuffer::LzCircularBuffer<W>>>
195
0
where
196
0
    W: io::Write,
197
{
198
0
    new_circular_with_memlimit(output, params, std::usize::MAX)
199
0
}
Unexecuted instantiation: lzma_rs::decode::lzma::new_circular::<std::io::cursor::Cursor<&mut [u8]>>
Unexecuted instantiation: lzma_rs::decode::lzma::new_circular::<suricata_htp::decompressors::BlockingCursor>
Unexecuted instantiation: lzma_rs::decode::lzma::new_circular::<_>
Unexecuted instantiation: lzma_rs::decode::lzma::new_circular::<std::io::cursor::Cursor<&mut [u8]>>
200
201
// Initialize decoder with circular buffer
202
69.0k
pub fn new_circular_with_memlimit<W>(
203
69.0k
    output: W,
204
69.0k
    params: LzmaParams,
205
69.0k
    memlimit: usize,
206
69.0k
) -> error::Result<DecoderState<W, lzbuffer::LzCircularBuffer<W>>>
207
69.0k
where
208
69.0k
    W: io::Write,
209
{
210
    // Decoder
211
69.0k
    let decoder = DecoderState {
212
69.0k
        _phantom: PhantomData,
213
69.0k
        output: lzbuffer::LzCircularBuffer::from_stream_with_memlimit(
214
69.0k
            output,
215
69.0k
            params.dict_size as usize,
216
69.0k
            memlimit,
217
69.0k
        ),
218
69.0k
        partial_input_buf: std::io::Cursor::new([0; MAX_REQUIRED_INPUT]),
219
69.0k
        lc: params.lc,
220
69.0k
        lp: params.lp,
221
69.0k
        pb: params.pb,
222
69.0k
        unpacked_size: params.unpacked_size,
223
69.0k
        literal_probs: vec![vec![0x400; 0x300]; 1 << (params.lc + params.lp)],
224
69.0k
        pos_slot_decoder: vec![rangecoder::BitTree::new(6); 4],
225
69.0k
        align_decoder: rangecoder::BitTree::new(4),
226
69.0k
        pos_decoders: [0x400; 115],
227
69.0k
        is_match: [0x400; 192],
228
69.0k
        is_rep: [0x400; 12],
229
69.0k
        is_rep_g0: [0x400; 12],
230
69.0k
        is_rep_g1: [0x400; 12],
231
69.0k
        is_rep_g2: [0x400; 12],
232
69.0k
        is_rep_0long: [0x400; 192],
233
69.0k
        state: 0,
234
69.0k
        rep: [0; 4],
235
69.0k
        len_decoder: rangecoder::LenDecoder::new(),
236
69.0k
        rep_len_decoder: rangecoder::LenDecoder::new(),
237
69.0k
    };
238
239
69.0k
    Ok(decoder)
240
69.0k
}
Unexecuted instantiation: lzma_rs::decode::lzma::new_circular_with_memlimit::<std::io::cursor::Cursor<&mut [u8]>>
lzma_rs::decode::lzma::new_circular_with_memlimit::<suricata_htp::decompressors::BlockingCursor>
Line
Count
Source
202
69.0k
pub fn new_circular_with_memlimit<W>(
203
69.0k
    output: W,
204
69.0k
    params: LzmaParams,
205
69.0k
    memlimit: usize,
206
69.0k
) -> error::Result<DecoderState<W, lzbuffer::LzCircularBuffer<W>>>
207
69.0k
where
208
69.0k
    W: io::Write,
209
{
210
    // Decoder
211
69.0k
    let decoder = DecoderState {
212
69.0k
        _phantom: PhantomData,
213
69.0k
        output: lzbuffer::LzCircularBuffer::from_stream_with_memlimit(
214
69.0k
            output,
215
69.0k
            params.dict_size as usize,
216
69.0k
            memlimit,
217
69.0k
        ),
218
69.0k
        partial_input_buf: std::io::Cursor::new([0; MAX_REQUIRED_INPUT]),
219
69.0k
        lc: params.lc,
220
69.0k
        lp: params.lp,
221
69.0k
        pb: params.pb,
222
69.0k
        unpacked_size: params.unpacked_size,
223
69.0k
        literal_probs: vec![vec![0x400; 0x300]; 1 << (params.lc + params.lp)],
224
69.0k
        pos_slot_decoder: vec![rangecoder::BitTree::new(6); 4],
225
69.0k
        align_decoder: rangecoder::BitTree::new(4),
226
69.0k
        pos_decoders: [0x400; 115],
227
69.0k
        is_match: [0x400; 192],
228
69.0k
        is_rep: [0x400; 12],
229
69.0k
        is_rep_g0: [0x400; 12],
230
69.0k
        is_rep_g1: [0x400; 12],
231
69.0k
        is_rep_g2: [0x400; 12],
232
69.0k
        is_rep_0long: [0x400; 192],
233
69.0k
        state: 0,
234
69.0k
        rep: [0; 4],
235
69.0k
        len_decoder: rangecoder::LenDecoder::new(),
236
69.0k
        rep_len_decoder: rangecoder::LenDecoder::new(),
237
69.0k
    };
238
239
69.0k
    Ok(decoder)
240
69.0k
}
Unexecuted instantiation: lzma_rs::decode::lzma::new_circular_with_memlimit::<_>
Unexecuted instantiation: lzma_rs::decode::lzma::new_circular_with_memlimit::<std::io::cursor::Cursor<&mut [u8]>>
241
242
impl<W, LZB> DecoderState<W, LZB>
243
where
244
    W: io::Write,
245
    LZB: lzbuffer::LzBuffer<W>,
246
{
247
0
    pub fn reset_state(&mut self, lc: u32, lp: u32, pb: u32) {
248
0
        self.lc = lc;
249
0
        self.lp = lp;
250
0
        self.pb = pb;
251
0
        self.literal_probs = vec![vec![0x400; 0x300]; 1 << (lc + lp)];
252
0
        self.pos_slot_decoder = vec![rangecoder::BitTree::new(6); 4];
253
0
        self.align_decoder = rangecoder::BitTree::new(4);
254
0
        self.pos_decoders = [0x400; 115];
255
0
        self.is_match = [0x400; 192];
256
0
        self.is_rep = [0x400; 12];
257
0
        self.is_rep_g0 = [0x400; 12];
258
0
        self.is_rep_g1 = [0x400; 12];
259
0
        self.is_rep_g2 = [0x400; 12];
260
0
        self.is_rep_0long = [0x400; 192];
261
0
        self.state = 0;
262
0
        self.rep = [0; 4];
263
0
        self.len_decoder = rangecoder::LenDecoder::new();
264
0
        self.rep_len_decoder = rangecoder::LenDecoder::new();
265
0
    }
266
267
0
    pub fn set_unpacked_size(&mut self, unpacked_size: Option<u64>) {
268
0
        self.unpacked_size = unpacked_size;
269
0
    }
270
271
2.95k
    pub fn process<'a, R: io::BufRead>(
272
2.95k
        &mut self,
273
2.95k
        rangecoder: &mut rangecoder::RangeDecoder<'a, R>,
274
2.95k
    ) -> error::Result<()> {
275
2.95k
        self.process_mode(rangecoder, ProcessingMode::Finish)
276
2.95k
    }
Unexecuted instantiation: <lzma_rs::decode::lzma::DecoderState<std::io::cursor::Cursor<&mut [u8]>, lzma_rs::decode::lzbuffer::LzCircularBuffer<std::io::cursor::Cursor<&mut [u8]>>>>::process::<std::io::cursor::Cursor<&[u8]>>
<lzma_rs::decode::lzma::DecoderState<suricata_htp::decompressors::BlockingCursor, lzma_rs::decode::lzbuffer::LzCircularBuffer<suricata_htp::decompressors::BlockingCursor>>>::process::<std::io::cursor::Cursor<&[u8]>>
Line
Count
Source
271
2.95k
    pub fn process<'a, R: io::BufRead>(
272
2.95k
        &mut self,
273
2.95k
        rangecoder: &mut rangecoder::RangeDecoder<'a, R>,
274
2.95k
    ) -> error::Result<()> {
275
2.95k
        self.process_mode(rangecoder, ProcessingMode::Finish)
276
2.95k
    }
Unexecuted instantiation: <lzma_rs::decode::lzma::DecoderState<_, _>>::process::<_>
Unexecuted instantiation: <lzma_rs::decode::lzma::DecoderState<std::io::cursor::Cursor<&mut [u8]>, lzma_rs::decode::lzbuffer::LzCircularBuffer<std::io::cursor::Cursor<&mut [u8]>>>>::process::<std::io::cursor::Cursor<&[u8]>>
277
278
    #[cfg(feature = "stream")]
279
95.9k
    pub fn process_stream<'a, R: io::BufRead>(
280
95.9k
        &mut self,
281
95.9k
        rangecoder: &mut rangecoder::RangeDecoder<'a, R>,
282
95.9k
    ) -> error::Result<()> {
283
95.9k
        self.process_mode(rangecoder, ProcessingMode::Partial)
284
95.9k
    }
Unexecuted instantiation: <lzma_rs::decode::lzma::DecoderState<std::io::cursor::Cursor<&mut [u8]>, lzma_rs::decode::lzbuffer::LzCircularBuffer<std::io::cursor::Cursor<&mut [u8]>>>>::process_stream::<&mut std::io::cursor::Cursor<&[u8]>>
<lzma_rs::decode::lzma::DecoderState<suricata_htp::decompressors::BlockingCursor, lzma_rs::decode::lzbuffer::LzCircularBuffer<suricata_htp::decompressors::BlockingCursor>>>::process_stream::<&mut std::io::cursor::Cursor<&[u8]>>
Line
Count
Source
279
95.9k
    pub fn process_stream<'a, R: io::BufRead>(
280
95.9k
        &mut self,
281
95.9k
        rangecoder: &mut rangecoder::RangeDecoder<'a, R>,
282
95.9k
    ) -> error::Result<()> {
283
95.9k
        self.process_mode(rangecoder, ProcessingMode::Partial)
284
95.9k
    }
Unexecuted instantiation: <lzma_rs::decode::lzma::DecoderState<_, _>>::process_stream::<_>
Unexecuted instantiation: <lzma_rs::decode::lzma::DecoderState<std::io::cursor::Cursor<&mut [u8]>, lzma_rs::decode::lzbuffer::LzCircularBuffer<std::io::cursor::Cursor<&mut [u8]>>>>::process_stream::<&mut std::io::cursor::Cursor<&[u8]>>
285
286
    /// Process the next iteration of the loop.
287
    ///
288
    /// If the update flag is true, the decoder's state will be updated.
289
    ///
290
    /// Returns `ProcessingStatus` to determine whether one should continue
291
    /// processing the loop.
292
2.21M
    fn process_next_inner<'a, R: io::BufRead>(
293
2.21M
        &mut self,
294
2.21M
        rangecoder: &mut rangecoder::RangeDecoder<'a, R>,
295
2.21M
        update: bool,
296
2.21M
    ) -> error::Result<ProcessingStatus> {
297
2.21M
        let pos_state = self.output.len() & ((1 << self.pb) - 1);
298
299
        // Literal
300
2.21M
        if !rangecoder.decode_bit(
301
            // TODO: assumes pb = 2 ??
302
2.21M
            &mut self.is_match[(self.state << 4) + pos_state],
303
2.21M
            update,
304
2.95k
        )? {
305
1.26M
            let byte: u8 = self.decode_literal(rangecoder, update)?;
306
307
1.24M
            if update {
308
                lzma_debug!("Literal: {}", byte);
309
1.12M
                self.output.append_literal(byte)?;
310
311
1.12M
                self.state = if self.state < 4 {
312
1.05M
                    0
313
65.4k
                } else if self.state < 10 {
314
47.3k
                    self.state - 3
315
                } else {
316
18.0k
                    self.state - 6
317
                };
318
127k
            }
319
1.24M
            return Ok(ProcessingStatus::Continue);
320
952k
        }
321
322
        // LZ
323
        let mut len: usize;
324
        // Distance is repeated from LRU
325
952k
        if rangecoder.decode_bit(&mut self.is_rep[self.state], update)? {
326
            // dist = rep[0]
327
852k
            if !rangecoder.decode_bit(&mut self.is_rep_g0[self.state], update)? {
328
                // len = 1
329
64.2k
                if !rangecoder.decode_bit(
330
64.2k
                    &mut self.is_rep_0long[(self.state << 4) + pos_state],
331
64.2k
                    update,
332
822
                )? {
333
                    // update state (short rep)
334
28.8k
                    if update {
335
17.7k
                        self.state = if self.state < 7 { 9 } else { 11 };
336
17.7k
                        let dist = self.rep[0] + 1;
337
17.7k
                        self.output.append_lz(1, dist)?;
338
11.1k
                    }
339
27.1k
                    return Ok(ProcessingStatus::Continue);
340
34.6k
                }
341
            // dist = rep[i]
342
            } else {
343
                let idx: usize;
344
785k
                if !rangecoder.decode_bit(&mut self.is_rep_g1[self.state], update)? {
345
41.2k
                    idx = 1;
346
742k
                } else if !rangecoder.decode_bit(&mut self.is_rep_g2[self.state], update)? {
347
26.7k
                    idx = 2;
348
713k
                } else {
349
713k
                    idx = 3;
350
713k
                }
351
781k
                if update {
352
                    // Update LRU
353
560k
                    let dist = self.rep[idx];
354
1.61M
                    for i in (0..idx).rev() {
355
1.61M
                        self.rep[i + 1] = self.rep[i];
356
1.61M
                    }
357
560k
                    self.rep[0] = dist
358
221k
                }
359
            }
360
361
816k
            len = self.rep_len_decoder.decode(rangecoder, pos_state, update)?;
362
363
800k
            if update {
364
                // update state (rep)
365
579k
                self.state = if self.state < 7 { 8 } else { 11 };
366
221k
            }
367
        // New distance
368
        } else {
369
98.7k
            if update {
370
48.6k
                // Update LRU
371
48.6k
                self.rep[3] = self.rep[2];
372
48.6k
                self.rep[2] = self.rep[1];
373
48.6k
                self.rep[1] = self.rep[0];
374
50.0k
            }
375
376
98.7k
            len = self.len_decoder.decode(rangecoder, pos_state, update)?;
377
378
93.8k
            if update {
379
                // update state (match)
380
48.5k
                self.state = if self.state < 7 { 7 } else { 10 };
381
45.3k
            }
382
383
93.8k
            let rep_0 = self.decode_distance(rangecoder, len, update)?;
384
385
81.5k
            if update {
386
48.3k
                self.rep[0] = rep_0;
387
48.3k
                if self.rep[0] == 0xFFFF_FFFF {
388
779
                    if rangecoder.is_finished_ok()? {
389
1
                        return Ok(ProcessingStatus::Finished);
390
778
                    }
391
778
                    return Err(error::Error::LzmaError(String::from(
392
778
                        "Found end-of-stream marker but more bytes are available",
393
778
                    )));
394
47.6k
                }
395
33.1k
            }
396
        }
397
398
881k
        if update {
399
626k
            len += 2;
400
401
626k
            let dist = self.rep[0] + 1;
402
626k
            self.output.append_lz(len, dist)?;
403
254k
        }
404
405
849k
        Ok(ProcessingStatus::Continue)
406
2.21M
    }
Unexecuted instantiation: <lzma_rs::decode::lzma::DecoderState<std::io::cursor::Cursor<&mut [u8]>, lzma_rs::decode::lzbuffer::LzCircularBuffer<std::io::cursor::Cursor<&mut [u8]>>>>::process_next_inner::<std::io::cursor::Cursor<&[u8]>>
Unexecuted instantiation: <lzma_rs::decode::lzma::DecoderState<std::io::cursor::Cursor<&mut [u8]>, lzma_rs::decode::lzbuffer::LzCircularBuffer<std::io::cursor::Cursor<&mut [u8]>>>>::process_next_inner::<&mut std::io::cursor::Cursor<&[u8]>>
<lzma_rs::decode::lzma::DecoderState<suricata_htp::decompressors::BlockingCursor, lzma_rs::decode::lzbuffer::LzCircularBuffer<suricata_htp::decompressors::BlockingCursor>>>::process_next_inner::<std::io::cursor::Cursor<&[u8]>>
Line
Count
Source
292
521k
    fn process_next_inner<'a, R: io::BufRead>(
293
521k
        &mut self,
294
521k
        rangecoder: &mut rangecoder::RangeDecoder<'a, R>,
295
521k
        update: bool,
296
521k
    ) -> error::Result<ProcessingStatus> {
297
521k
        let pos_state = self.output.len() & ((1 << self.pb) - 1);
298
299
        // Literal
300
521k
        if !rangecoder.decode_bit(
301
            // TODO: assumes pb = 2 ??
302
521k
            &mut self.is_match[(self.state << 4) + pos_state],
303
521k
            update,
304
2.95k
        )? {
305
166k
            let byte: u8 = self.decode_literal(rangecoder, update)?;
306
307
152k
            if update {
308
                lzma_debug!("Literal: {}", byte);
309
25.2k
                self.output.append_literal(byte)?;
310
311
25.2k
                self.state = if self.state < 4 {
312
5.31k
                    0
313
19.8k
                } else if self.state < 10 {
314
12.4k
                    self.state - 3
315
                } else {
316
7.44k
                    self.state - 6
317
                };
318
127k
            }
319
152k
            return Ok(ProcessingStatus::Continue);
320
351k
        }
321
322
        // LZ
323
        let mut len: usize;
324
        // Distance is repeated from LRU
325
351k
        if rangecoder.decode_bit(&mut self.is_rep[self.state], update)? {
326
            // dist = rep[0]
327
286k
            if !rangecoder.decode_bit(&mut self.is_rep_g0[self.state], update)? {
328
                // len = 1
329
35.2k
                if !rangecoder.decode_bit(
330
35.2k
                    &mut self.is_rep_0long[(self.state << 4) + pos_state],
331
35.2k
                    update,
332
822
                )? {
333
                    // update state (short rep)
334
14.4k
                    if update {
335
3.35k
                        self.state = if self.state < 7 { 9 } else { 11 };
336
3.35k
                        let dist = self.rep[0] + 1;
337
3.35k
                        self.output.append_lz(1, dist)?;
338
11.1k
                    }
339
14.4k
                    return Ok(ProcessingStatus::Continue);
340
19.9k
                }
341
            // dist = rep[i]
342
            } else {
343
                let idx: usize;
344
247k
                if !rangecoder.decode_bit(&mut self.is_rep_g1[self.state], update)? {
345
23.8k
                    idx = 1;
346
222k
                } else if !rangecoder.decode_bit(&mut self.is_rep_g2[self.state], update)? {
347
16.5k
                    idx = 2;
348
203k
                } else {
349
203k
                    idx = 3;
350
203k
                }
351
244k
                if update {
352
                    // Update LRU
353
22.9k
                    let dist = self.rep[idx];
354
51.7k
                    for i in (0..idx).rev() {
355
51.7k
                        self.rep[i + 1] = self.rep[i];
356
51.7k
                    }
357
22.9k
                    self.rep[0] = dist
358
221k
                }
359
            }
360
361
263k
            len = self.rep_len_decoder.decode(rangecoder, pos_state, update)?;
362
363
248k
            if update {
364
                // update state (rep)
365
26.7k
                self.state = if self.state < 7 { 8 } else { 11 };
366
221k
            }
367
        // New distance
368
        } else {
369
64.7k
            if update {
370
14.6k
                // Update LRU
371
14.6k
                self.rep[3] = self.rep[2];
372
14.6k
                self.rep[2] = self.rep[1];
373
14.6k
                self.rep[1] = self.rep[0];
374
50.0k
            }
375
376
64.7k
            len = self.len_decoder.decode(rangecoder, pos_state, update)?;
377
378
59.8k
            if update {
379
                // update state (match)
380
14.5k
                self.state = if self.state < 7 { 7 } else { 10 };
381
45.3k
            }
382
383
59.8k
            let rep_0 = self.decode_distance(rangecoder, len, update)?;
384
385
47.5k
            if update {
386
14.4k
                self.rep[0] = rep_0;
387
14.4k
                if self.rep[0] == 0xFFFF_FFFF {
388
322
                    if rangecoder.is_finished_ok()? {
389
0
                        return Ok(ProcessingStatus::Finished);
390
322
                    }
391
322
                    return Err(error::Error::LzmaError(String::from(
392
322
                        "Found end-of-stream marker but more bytes are available",
393
322
                    )));
394
14.1k
                }
395
33.1k
            }
396
        }
397
398
295k
        if update {
399
40.9k
            len += 2;
400
401
40.9k
            let dist = self.rep[0] + 1;
402
40.9k
            self.output.append_lz(len, dist)?;
403
254k
        }
404
405
289k
        Ok(ProcessingStatus::Continue)
406
521k
    }
<lzma_rs::decode::lzma::DecoderState<suricata_htp::decompressors::BlockingCursor, lzma_rs::decode::lzbuffer::LzCircularBuffer<suricata_htp::decompressors::BlockingCursor>>>::process_next_inner::<&mut std::io::cursor::Cursor<&[u8]>>
Line
Count
Source
292
1.69M
    fn process_next_inner<'a, R: io::BufRead>(
293
1.69M
        &mut self,
294
1.69M
        rangecoder: &mut rangecoder::RangeDecoder<'a, R>,
295
1.69M
        update: bool,
296
1.69M
    ) -> error::Result<ProcessingStatus> {
297
1.69M
        let pos_state = self.output.len() & ((1 << self.pb) - 1);
298
299
        // Literal
300
1.69M
        if !rangecoder.decode_bit(
301
            // TODO: assumes pb = 2 ??
302
1.69M
            &mut self.is_match[(self.state << 4) + pos_state],
303
1.69M
            update,
304
0
        )? {
305
1.09M
            let byte: u8 = self.decode_literal(rangecoder, update)?;
306
307
1.09M
            if update {
308
                lzma_debug!("Literal: {}", byte);
309
1.09M
                self.output.append_literal(byte)?;
310
311
1.09M
                self.state = if self.state < 4 {
312
1.04M
                    0
313
45.5k
                } else if self.state < 10 {
314
34.9k
                    self.state - 3
315
                } else {
316
10.6k
                    self.state - 6
317
                };
318
0
            }
319
1.09M
            return Ok(ProcessingStatus::Continue);
320
600k
        }
321
322
        // LZ
323
        let mut len: usize;
324
        // Distance is repeated from LRU
325
600k
        if rangecoder.decode_bit(&mut self.is_rep[self.state], update)? {
326
            // dist = rep[0]
327
566k
            if !rangecoder.decode_bit(&mut self.is_rep_g0[self.state], update)? {
328
                // len = 1
329
29.0k
                if !rangecoder.decode_bit(
330
29.0k
                    &mut self.is_rep_0long[(self.state << 4) + pos_state],
331
29.0k
                    update,
332
0
                )? {
333
                    // update state (short rep)
334
14.3k
                    if update {
335
14.3k
                        self.state = if self.state < 7 { 9 } else { 11 };
336
14.3k
                        let dist = self.rep[0] + 1;
337
14.3k
                        self.output.append_lz(1, dist)?;
338
0
                    }
339
12.7k
                    return Ok(ProcessingStatus::Continue);
340
14.6k
                }
341
            // dist = rep[i]
342
            } else {
343
                let idx: usize;
344
537k
                if !rangecoder.decode_bit(&mut self.is_rep_g1[self.state], update)? {
345
17.4k
                    idx = 1;
346
520k
                } else if !rangecoder.decode_bit(&mut self.is_rep_g2[self.state], update)? {
347
10.1k
                    idx = 2;
348
509k
                } else {
349
509k
                    idx = 3;
350
509k
                }
351
537k
                if update {
352
                    // Update LRU
353
537k
                    let dist = self.rep[idx];
354
1.56M
                    for i in (0..idx).rev() {
355
1.56M
                        self.rep[i + 1] = self.rep[i];
356
1.56M
                    }
357
537k
                    self.rep[0] = dist
358
0
                }
359
            }
360
361
552k
            len = self.rep_len_decoder.decode(rangecoder, pos_state, update)?;
362
363
552k
            if update {
364
                // update state (rep)
365
552k
                self.state = if self.state < 7 { 8 } else { 11 };
366
0
            }
367
        // New distance
368
        } else {
369
33.9k
            if update {
370
33.9k
                // Update LRU
371
33.9k
                self.rep[3] = self.rep[2];
372
33.9k
                self.rep[2] = self.rep[1];
373
33.9k
                self.rep[1] = self.rep[0];
374
33.9k
            }
375
376
33.9k
            len = self.len_decoder.decode(rangecoder, pos_state, update)?;
377
378
33.9k
            if update {
379
                // update state (match)
380
33.9k
                self.state = if self.state < 7 { 7 } else { 10 };
381
0
            }
382
383
33.9k
            let rep_0 = self.decode_distance(rangecoder, len, update)?;
384
385
33.9k
            if update {
386
33.9k
                self.rep[0] = rep_0;
387
33.9k
                if self.rep[0] == 0xFFFF_FFFF {
388
457
                    if rangecoder.is_finished_ok()? {
389
1
                        return Ok(ProcessingStatus::Finished);
390
456
                    }
391
456
                    return Err(error::Error::LzmaError(String::from(
392
456
                        "Found end-of-stream marker but more bytes are available",
393
456
                    )));
394
33.5k
                }
395
0
            }
396
        }
397
398
585k
        if update {
399
585k
            len += 2;
400
401
585k
            let dist = self.rep[0] + 1;
402
585k
            self.output.append_lz(len, dist)?;
403
0
        }
404
405
559k
        Ok(ProcessingStatus::Continue)
406
1.69M
    }
Unexecuted instantiation: <lzma_rs::decode::lzma::DecoderState<_, _>>::process_next_inner::<_>
Unexecuted instantiation: <lzma_rs::decode::lzma::DecoderState<std::io::cursor::Cursor<&mut [u8]>, lzma_rs::decode::lzbuffer::LzCircularBuffer<std::io::cursor::Cursor<&mut [u8]>>>>::process_next_inner::<std::io::cursor::Cursor<&[u8]>>
Unexecuted instantiation: <lzma_rs::decode::lzma::DecoderState<std::io::cursor::Cursor<&mut [u8]>, lzma_rs::decode::lzbuffer::LzCircularBuffer<std::io::cursor::Cursor<&mut [u8]>>>>::process_next_inner::<&mut std::io::cursor::Cursor<&[u8]>>
407
408
1.76M
    fn process_next<'a, R: io::BufRead>(
409
1.76M
        &mut self,
410
1.76M
        rangecoder: &mut rangecoder::RangeDecoder<'a, R>,
411
1.76M
    ) -> error::Result<ProcessingStatus> {
412
1.76M
        self.process_next_inner(rangecoder, true)
413
1.76M
    }
Unexecuted instantiation: <lzma_rs::decode::lzma::DecoderState<std::io::cursor::Cursor<&mut [u8]>, lzma_rs::decode::lzbuffer::LzCircularBuffer<std::io::cursor::Cursor<&mut [u8]>>>>::process_next::<std::io::cursor::Cursor<&[u8]>>
Unexecuted instantiation: <lzma_rs::decode::lzma::DecoderState<std::io::cursor::Cursor<&mut [u8]>, lzma_rs::decode::lzbuffer::LzCircularBuffer<std::io::cursor::Cursor<&mut [u8]>>>>::process_next::<&mut std::io::cursor::Cursor<&[u8]>>
<lzma_rs::decode::lzma::DecoderState<suricata_htp::decompressors::BlockingCursor, lzma_rs::decode::lzbuffer::LzCircularBuffer<suricata_htp::decompressors::BlockingCursor>>>::process_next::<std::io::cursor::Cursor<&[u8]>>
Line
Count
Source
408
71.4k
    fn process_next<'a, R: io::BufRead>(
409
71.4k
        &mut self,
410
71.4k
        rangecoder: &mut rangecoder::RangeDecoder<'a, R>,
411
71.4k
    ) -> error::Result<ProcessingStatus> {
412
71.4k
        self.process_next_inner(rangecoder, true)
413
71.4k
    }
<lzma_rs::decode::lzma::DecoderState<suricata_htp::decompressors::BlockingCursor, lzma_rs::decode::lzbuffer::LzCircularBuffer<suricata_htp::decompressors::BlockingCursor>>>::process_next::<&mut std::io::cursor::Cursor<&[u8]>>
Line
Count
Source
408
1.69M
    fn process_next<'a, R: io::BufRead>(
409
1.69M
        &mut self,
410
1.69M
        rangecoder: &mut rangecoder::RangeDecoder<'a, R>,
411
1.69M
    ) -> error::Result<ProcessingStatus> {
412
1.69M
        self.process_next_inner(rangecoder, true)
413
1.69M
    }
Unexecuted instantiation: <lzma_rs::decode::lzma::DecoderState<_, _>>::process_next::<_>
Unexecuted instantiation: <lzma_rs::decode::lzma::DecoderState<std::io::cursor::Cursor<&mut [u8]>, lzma_rs::decode::lzbuffer::LzCircularBuffer<std::io::cursor::Cursor<&mut [u8]>>>>::process_next::<std::io::cursor::Cursor<&[u8]>>
Unexecuted instantiation: <lzma_rs::decode::lzma::DecoderState<std::io::cursor::Cursor<&mut [u8]>, lzma_rs::decode::lzbuffer::LzCircularBuffer<std::io::cursor::Cursor<&mut [u8]>>>>::process_next::<&mut std::io::cursor::Cursor<&[u8]>>
414
415
    /// Try to process the next iteration of the loop.
416
    ///
417
    /// This will check to see if there is enough data to consume and advance the
418
    /// decompressor. Needed in streaming mode to avoid corrupting the state while
419
    /// processing incomplete chunks of data.
420
449k
    fn try_process_next(&mut self, buf: &[u8], range: u32, code: u32) -> error::Result<()> {
421
449k
        let mut temp = std::io::Cursor::new(buf);
422
449k
        let mut rangecoder = rangecoder::RangeDecoder::from_parts(&mut temp, range, code);
423
449k
        let _ = self.process_next_inner(&mut rangecoder, false)?;
424
393k
        Ok(())
425
449k
    }
Unexecuted instantiation: <lzma_rs::decode::lzma::DecoderState<std::io::cursor::Cursor<&mut [u8]>, lzma_rs::decode::lzbuffer::LzCircularBuffer<std::io::cursor::Cursor<&mut [u8]>>>>::try_process_next
<lzma_rs::decode::lzma::DecoderState<suricata_htp::decompressors::BlockingCursor, lzma_rs::decode::lzbuffer::LzCircularBuffer<suricata_htp::decompressors::BlockingCursor>>>::try_process_next
Line
Count
Source
420
449k
    fn try_process_next(&mut self, buf: &[u8], range: u32, code: u32) -> error::Result<()> {
421
449k
        let mut temp = std::io::Cursor::new(buf);
422
449k
        let mut rangecoder = rangecoder::RangeDecoder::from_parts(&mut temp, range, code);
423
449k
        let _ = self.process_next_inner(&mut rangecoder, false)?;
424
393k
        Ok(())
425
449k
    }
Unexecuted instantiation: <lzma_rs::decode::lzma::DecoderState<_, _>>::try_process_next
Unexecuted instantiation: <lzma_rs::decode::lzma::DecoderState<std::io::cursor::Cursor<&mut [u8]>, lzma_rs::decode::lzbuffer::LzCircularBuffer<std::io::cursor::Cursor<&mut [u8]>>>>::try_process_next
426
427
    /// Utility function to read data into the partial input buffer.
428
125k
    fn read_partial_input_buf<'a, R: io::BufRead>(
429
125k
        &mut self,
430
125k
        rangecoder: &mut rangecoder::RangeDecoder<'a, R>,
431
125k
    ) -> error::Result<()> {
432
        // Fill as much of the tmp buffer as possible
433
125k
        let start = self.partial_input_buf.position() as usize;
434
125k
        let bytes_read =
435
125k
            rangecoder.read_into(&mut self.partial_input_buf.get_mut()[start..])? as u64;
436
125k
        self.partial_input_buf
437
125k
            .set_position(self.partial_input_buf.position() + bytes_read);
438
125k
        Ok(())
439
125k
    }
Unexecuted instantiation: <lzma_rs::decode::lzma::DecoderState<std::io::cursor::Cursor<&mut [u8]>, lzma_rs::decode::lzbuffer::LzCircularBuffer<std::io::cursor::Cursor<&mut [u8]>>>>::read_partial_input_buf::<std::io::cursor::Cursor<&[u8]>>
Unexecuted instantiation: <lzma_rs::decode::lzma::DecoderState<std::io::cursor::Cursor<&mut [u8]>, lzma_rs::decode::lzbuffer::LzCircularBuffer<std::io::cursor::Cursor<&mut [u8]>>>>::read_partial_input_buf::<&mut std::io::cursor::Cursor<&[u8]>>
<lzma_rs::decode::lzma::DecoderState<suricata_htp::decompressors::BlockingCursor, lzma_rs::decode::lzbuffer::LzCircularBuffer<suricata_htp::decompressors::BlockingCursor>>>::read_partial_input_buf::<std::io::cursor::Cursor<&[u8]>>
Line
Count
Source
428
233
    fn read_partial_input_buf<'a, R: io::BufRead>(
429
233
        &mut self,
430
233
        rangecoder: &mut rangecoder::RangeDecoder<'a, R>,
431
233
    ) -> error::Result<()> {
432
        // Fill as much of the tmp buffer as possible
433
233
        let start = self.partial_input_buf.position() as usize;
434
233
        let bytes_read =
435
233
            rangecoder.read_into(&mut self.partial_input_buf.get_mut()[start..])? as u64;
436
233
        self.partial_input_buf
437
233
            .set_position(self.partial_input_buf.position() + bytes_read);
438
233
        Ok(())
439
233
    }
<lzma_rs::decode::lzma::DecoderState<suricata_htp::decompressors::BlockingCursor, lzma_rs::decode::lzbuffer::LzCircularBuffer<suricata_htp::decompressors::BlockingCursor>>>::read_partial_input_buf::<&mut std::io::cursor::Cursor<&[u8]>>
Line
Count
Source
428
125k
    fn read_partial_input_buf<'a, R: io::BufRead>(
429
125k
        &mut self,
430
125k
        rangecoder: &mut rangecoder::RangeDecoder<'a, R>,
431
125k
    ) -> error::Result<()> {
432
        // Fill as much of the tmp buffer as possible
433
125k
        let start = self.partial_input_buf.position() as usize;
434
125k
        let bytes_read =
435
125k
            rangecoder.read_into(&mut self.partial_input_buf.get_mut()[start..])? as u64;
436
125k
        self.partial_input_buf
437
125k
            .set_position(self.partial_input_buf.position() + bytes_read);
438
125k
        Ok(())
439
125k
    }
Unexecuted instantiation: <lzma_rs::decode::lzma::DecoderState<_, _>>::read_partial_input_buf::<_>
Unexecuted instantiation: <lzma_rs::decode::lzma::DecoderState<std::io::cursor::Cursor<&mut [u8]>, lzma_rs::decode::lzbuffer::LzCircularBuffer<std::io::cursor::Cursor<&mut [u8]>>>>::read_partial_input_buf::<std::io::cursor::Cursor<&[u8]>>
Unexecuted instantiation: <lzma_rs::decode::lzma::DecoderState<std::io::cursor::Cursor<&mut [u8]>, lzma_rs::decode::lzbuffer::LzCircularBuffer<std::io::cursor::Cursor<&mut [u8]>>>>::read_partial_input_buf::<&mut std::io::cursor::Cursor<&[u8]>>
440
441
98.9k
    fn process_mode<'a, R: io::BufRead>(
442
98.9k
        &mut self,
443
98.9k
        mut rangecoder: &mut rangecoder::RangeDecoder<'a, R>,
444
98.9k
        mode: ProcessingMode,
445
98.9k
    ) -> error::Result<()> {
446
        loop {
447
1.83M
            if let Some(unpacked_size) = self.unpacked_size {
448
1.78M
                if self.output.len() as u64 >= unpacked_size {
449
5.90k
                    break;
450
1.78M
                }
451
43.4k
            } else if match mode {
452
                ProcessingMode::Partial => {
453
43.2k
                    rangecoder.is_eof()? && self.partial_input_buf.position() as usize == 0
454
                }
455
                ProcessingMode::Finish => {
456
200
                    rangecoder.is_finished_ok()? && self.partial_input_buf.position() as usize == 0
457
                }
458
            } {
459
537
                break;
460
42.9k
            }
461
462
1.82M
            if self.partial_input_buf.position() as usize > 0 {
463
73.0k
                self.read_partial_input_buf(rangecoder)?;
464
73.0k
                let tmp = *self.partial_input_buf.get_ref();
465
466
                // Check if we need more data to advance the decompressor
467
73.0k
                if mode == ProcessingMode::Partial
468
72.7k
                    && (self.partial_input_buf.position() as usize) < MAX_REQUIRED_INPUT
469
41.3k
                    && self
470
41.3k
                        .try_process_next(
471
41.3k
                            &tmp[..self.partial_input_buf.position() as usize],
472
41.3k
                            rangecoder.range,
473
41.3k
                            rangecoder.code,
474
41.3k
                        )
475
41.3k
                        .is_err()
476
                {
477
3.24k
                    return Ok(());
478
69.7k
                }
479
480
                // Run the decompressor on the tmp buffer
481
69.7k
                let mut tmp_reader =
482
69.7k
                    io::Cursor::new(&tmp[..self.partial_input_buf.position() as usize]);
483
69.7k
                let mut tmp_rangecoder = rangecoder::RangeDecoder::from_parts(
484
69.7k
                    &mut tmp_reader,
485
69.7k
                    rangecoder.range,
486
69.7k
                    rangecoder.code,
487
                );
488
69.7k
                let res = self.process_next(&mut tmp_rangecoder)?;
489
490
                // Update the actual rangecoder
491
63.5k
                rangecoder.set(tmp_rangecoder.range, tmp_rangecoder.code);
492
493
                // Update tmp buffer
494
63.5k
                let end = self.partial_input_buf.position();
495
63.5k
                let new_len = end - tmp_reader.position();
496
63.5k
                self.partial_input_buf.get_mut()[..new_len as usize]
497
63.5k
                    .copy_from_slice(&tmp[tmp_reader.position() as usize..end as usize]);
498
63.5k
                self.partial_input_buf.set_position(new_len);
499
500
63.5k
                if res == ProcessingStatus::Finished {
501
0
                    break;
502
63.5k
                };
503
            } else {
504
1.75M
                let buf: &[u8] = rangecoder.stream.fill_buf()?;
505
1.75M
                if mode == ProcessingMode::Partial
506
1.74M
                    && buf.len() < MAX_REQUIRED_INPUT
507
408k
                    && self
508
408k
                        .try_process_next(buf, rangecoder.range, rangecoder.code)
509
408k
                        .is_err()
510
                {
511
52.7k
                    return self.read_partial_input_buf(rangecoder);
512
1.69M
                }
513
514
1.69M
                if self.process_next(&mut rangecoder)? == ProcessingStatus::Finished {
515
1
                    break;
516
1.66M
                };
517
            }
518
        }
519
520
6.44k
        if let Some(len) = self.unpacked_size {
521
5.90k
            if mode == ProcessingMode::Finish && len != self.output.len() as u64 {
522
67
                return Err(error::Error::LzmaError(format!(
523
67
                    "Expected unpacked size of {} but decompressed to {}",
524
67
                    len,
525
67
                    self.output.len()
526
67
                )));
527
5.84k
            }
528
538
        }
529
530
6.38k
        Ok(())
531
98.9k
    }
Unexecuted instantiation: <lzma_rs::decode::lzma::DecoderState<std::io::cursor::Cursor<&mut [u8]>, lzma_rs::decode::lzbuffer::LzCircularBuffer<std::io::cursor::Cursor<&mut [u8]>>>>::process_mode::<std::io::cursor::Cursor<&[u8]>>
Unexecuted instantiation: <lzma_rs::decode::lzma::DecoderState<std::io::cursor::Cursor<&mut [u8]>, lzma_rs::decode::lzbuffer::LzCircularBuffer<std::io::cursor::Cursor<&mut [u8]>>>>::process_mode::<&mut std::io::cursor::Cursor<&[u8]>>
<lzma_rs::decode::lzma::DecoderState<suricata_htp::decompressors::BlockingCursor, lzma_rs::decode::lzbuffer::LzCircularBuffer<suricata_htp::decompressors::BlockingCursor>>>::process_mode::<std::io::cursor::Cursor<&[u8]>>
Line
Count
Source
441
2.95k
    fn process_mode<'a, R: io::BufRead>(
442
2.95k
        &mut self,
443
2.95k
        mut rangecoder: &mut rangecoder::RangeDecoder<'a, R>,
444
2.95k
        mode: ProcessingMode,
445
2.95k
    ) -> error::Result<()> {
446
        loop {
447
3.12k
            if let Some(unpacked_size) = self.unpacked_size {
448
2.92k
                if self.output.len() as u64 >= unpacked_size {
449
1.17k
                    break;
450
1.75k
                }
451
200
            } else if match mode {
452
                ProcessingMode::Partial => {
453
0
                    rangecoder.is_eof()? && self.partial_input_buf.position() as usize == 0
454
                }
455
                ProcessingMode::Finish => {
456
200
                    rangecoder.is_finished_ok()? && self.partial_input_buf.position() as usize == 0
457
                }
458
            } {
459
3
                break;
460
197
            }
461
462
1.95k
            if self.partial_input_buf.position() as usize > 0 {
463
233
                self.read_partial_input_buf(rangecoder)?;
464
233
                let tmp = *self.partial_input_buf.get_ref();
465
466
                // Check if we need more data to advance the decompressor
467
233
                if mode == ProcessingMode::Partial
468
0
                    && (self.partial_input_buf.position() as usize) < MAX_REQUIRED_INPUT
469
0
                    && self
470
0
                        .try_process_next(
471
0
                            &tmp[..self.partial_input_buf.position() as usize],
472
0
                            rangecoder.range,
473
0
                            rangecoder.code,
474
0
                        )
475
0
                        .is_err()
476
                {
477
0
                    return Ok(());
478
233
                }
479
480
                // Run the decompressor on the tmp buffer
481
233
                let mut tmp_reader =
482
233
                    io::Cursor::new(&tmp[..self.partial_input_buf.position() as usize]);
483
233
                let mut tmp_rangecoder = rangecoder::RangeDecoder::from_parts(
484
233
                    &mut tmp_reader,
485
233
                    rangecoder.range,
486
233
                    rangecoder.code,
487
                );
488
233
                let res = self.process_next(&mut tmp_rangecoder)?;
489
490
                // Update the actual rangecoder
491
0
                rangecoder.set(tmp_rangecoder.range, tmp_rangecoder.code);
492
493
                // Update tmp buffer
494
0
                let end = self.partial_input_buf.position();
495
0
                let new_len = end - tmp_reader.position();
496
0
                self.partial_input_buf.get_mut()[..new_len as usize]
497
0
                    .copy_from_slice(&tmp[tmp_reader.position() as usize..end as usize]);
498
0
                self.partial_input_buf.set_position(new_len);
499
500
0
                if res == ProcessingStatus::Finished {
501
0
                    break;
502
0
                };
503
            } else {
504
1.71k
                let buf: &[u8] = rangecoder.stream.fill_buf()?;
505
1.71k
                if mode == ProcessingMode::Partial
506
0
                    && buf.len() < MAX_REQUIRED_INPUT
507
0
                    && self
508
0
                        .try_process_next(buf, rangecoder.range, rangecoder.code)
509
0
                        .is_err()
510
                {
511
0
                    return self.read_partial_input_buf(rangecoder);
512
1.71k
                }
513
514
1.71k
                if self.process_next(&mut rangecoder)? == ProcessingStatus::Finished {
515
0
                    break;
516
174
                };
517
            }
518
        }
519
520
1.17k
        if let Some(len) = self.unpacked_size {
521
1.17k
            if mode == ProcessingMode::Finish && len != self.output.len() as u64 {
522
67
                return Err(error::Error::LzmaError(format!(
523
67
                    "Expected unpacked size of {} but decompressed to {}",
524
67
                    len,
525
67
                    self.output.len()
526
67
                )));
527
1.10k
            }
528
3
        }
529
530
1.10k
        Ok(())
531
2.95k
    }
<lzma_rs::decode::lzma::DecoderState<suricata_htp::decompressors::BlockingCursor, lzma_rs::decode::lzbuffer::LzCircularBuffer<suricata_htp::decompressors::BlockingCursor>>>::process_mode::<&mut std::io::cursor::Cursor<&[u8]>>
Line
Count
Source
441
95.9k
    fn process_mode<'a, R: io::BufRead>(
442
95.9k
        &mut self,
443
95.9k
        mut rangecoder: &mut rangecoder::RangeDecoder<'a, R>,
444
95.9k
        mode: ProcessingMode,
445
95.9k
    ) -> error::Result<()> {
446
        loop {
447
1.82M
            if let Some(unpacked_size) = self.unpacked_size {
448
1.78M
                if self.output.len() as u64 >= unpacked_size {
449
4.73k
                    break;
450
1.77M
                }
451
43.2k
            } else if match mode {
452
                ProcessingMode::Partial => {
453
43.2k
                    rangecoder.is_eof()? && self.partial_input_buf.position() as usize == 0
454
                }
455
                ProcessingMode::Finish => {
456
0
                    rangecoder.is_finished_ok()? && self.partial_input_buf.position() as usize == 0
457
                }
458
            } {
459
534
                break;
460
42.7k
            }
461
462
1.82M
            if self.partial_input_buf.position() as usize > 0 {
463
72.7k
                self.read_partial_input_buf(rangecoder)?;
464
72.7k
                let tmp = *self.partial_input_buf.get_ref();
465
466
                // Check if we need more data to advance the decompressor
467
72.7k
                if mode == ProcessingMode::Partial
468
72.7k
                    && (self.partial_input_buf.position() as usize) < MAX_REQUIRED_INPUT
469
41.3k
                    && self
470
41.3k
                        .try_process_next(
471
41.3k
                            &tmp[..self.partial_input_buf.position() as usize],
472
41.3k
                            rangecoder.range,
473
41.3k
                            rangecoder.code,
474
41.3k
                        )
475
41.3k
                        .is_err()
476
                {
477
3.24k
                    return Ok(());
478
69.5k
                }
479
480
                // Run the decompressor on the tmp buffer
481
69.5k
                let mut tmp_reader =
482
69.5k
                    io::Cursor::new(&tmp[..self.partial_input_buf.position() as usize]);
483
69.5k
                let mut tmp_rangecoder = rangecoder::RangeDecoder::from_parts(
484
69.5k
                    &mut tmp_reader,
485
69.5k
                    rangecoder.range,
486
69.5k
                    rangecoder.code,
487
                );
488
69.5k
                let res = self.process_next(&mut tmp_rangecoder)?;
489
490
                // Update the actual rangecoder
491
63.5k
                rangecoder.set(tmp_rangecoder.range, tmp_rangecoder.code);
492
493
                // Update tmp buffer
494
63.5k
                let end = self.partial_input_buf.position();
495
63.5k
                let new_len = end - tmp_reader.position();
496
63.5k
                self.partial_input_buf.get_mut()[..new_len as usize]
497
63.5k
                    .copy_from_slice(&tmp[tmp_reader.position() as usize..end as usize]);
498
63.5k
                self.partial_input_buf.set_position(new_len);
499
500
63.5k
                if res == ProcessingStatus::Finished {
501
0
                    break;
502
63.5k
                };
503
            } else {
504
1.74M
                let buf: &[u8] = rangecoder.stream.fill_buf()?;
505
1.74M
                if mode == ProcessingMode::Partial
506
1.74M
                    && buf.len() < MAX_REQUIRED_INPUT
507
408k
                    && self
508
408k
                        .try_process_next(buf, rangecoder.range, rangecoder.code)
509
408k
                        .is_err()
510
                {
511
52.7k
                    return self.read_partial_input_buf(rangecoder);
512
1.69M
                }
513
514
1.69M
                if self.process_next(&mut rangecoder)? == ProcessingStatus::Finished {
515
1
                    break;
516
1.66M
                };
517
            }
518
        }
519
520
5.27k
        if let Some(len) = self.unpacked_size {
521
4.73k
            if mode == ProcessingMode::Finish && len != self.output.len() as u64 {
522
0
                return Err(error::Error::LzmaError(format!(
523
0
                    "Expected unpacked size of {} but decompressed to {}",
524
0
                    len,
525
0
                    self.output.len()
526
0
                )));
527
4.73k
            }
528
535
        }
529
530
5.27k
        Ok(())
531
95.9k
    }
Unexecuted instantiation: <lzma_rs::decode::lzma::DecoderState<_, _>>::process_mode::<_>
Unexecuted instantiation: <lzma_rs::decode::lzma::DecoderState<std::io::cursor::Cursor<&mut [u8]>, lzma_rs::decode::lzbuffer::LzCircularBuffer<std::io::cursor::Cursor<&mut [u8]>>>>::process_mode::<std::io::cursor::Cursor<&[u8]>>
Unexecuted instantiation: <lzma_rs::decode::lzma::DecoderState<std::io::cursor::Cursor<&mut [u8]>, lzma_rs::decode::lzbuffer::LzCircularBuffer<std::io::cursor::Cursor<&mut [u8]>>>>::process_mode::<&mut std::io::cursor::Cursor<&[u8]>>
532
533
1.26M
    fn decode_literal<'a, R: io::BufRead>(
534
1.26M
        &mut self,
535
1.26M
        rangecoder: &mut rangecoder::RangeDecoder<'a, R>,
536
1.26M
        update: bool,
537
1.26M
    ) -> error::Result<u8> {
538
1.26M
        let def_prev_byte = 0u8;
539
1.26M
        let prev_byte = self.output.last_or(def_prev_byte) as usize;
540
541
1.26M
        let mut result: usize = 1;
542
1.26M
        let lit_state =
543
1.26M
            ((self.output.len() & ((1 << self.lp) - 1)) << self.lc) + (prev_byte >> (8 - self.lc));
544
1.26M
        let probs = &mut self.literal_probs[lit_state];
545
546
1.26M
        if self.state >= 7 {
547
76.3k
            let mut match_byte = self.output.last_n(self.rep[0] + 1)? as usize;
548
549
157k
            while result < 0x100 {
550
155k
                let match_bit = (match_byte >> 7) & 1;
551
155k
                match_byte <<= 1;
552
155k
                let bit = rangecoder
553
155k
                    .decode_bit(&mut probs[((1 + match_bit) << 8) + result], update)?
554
                    as usize;
555
155k
                result = (result << 1) ^ bit;
556
155k
                if match_bit != bit {
557
74.3k
                    break;
558
81.0k
                }
559
            }
560
1.18M
        }
561
562
11.1M
        while result < 0x100 {
563
9.90M
            result = (result << 1) ^ (rangecoder.decode_bit(&mut probs[result], update)? as usize);
564
        }
565
566
1.24M
        Ok((result - 0x100) as u8)
567
1.26M
    }
Unexecuted instantiation: <lzma_rs::decode::lzma::DecoderState<std::io::cursor::Cursor<&mut [u8]>, lzma_rs::decode::lzbuffer::LzCircularBuffer<std::io::cursor::Cursor<&mut [u8]>>>>::decode_literal::<std::io::cursor::Cursor<&[u8]>>
Unexecuted instantiation: <lzma_rs::decode::lzma::DecoderState<std::io::cursor::Cursor<&mut [u8]>, lzma_rs::decode::lzbuffer::LzCircularBuffer<std::io::cursor::Cursor<&mut [u8]>>>>::decode_literal::<&mut std::io::cursor::Cursor<&[u8]>>
<lzma_rs::decode::lzma::DecoderState<suricata_htp::decompressors::BlockingCursor, lzma_rs::decode::lzbuffer::LzCircularBuffer<suricata_htp::decompressors::BlockingCursor>>>::decode_literal::<std::io::cursor::Cursor<&[u8]>>
Line
Count
Source
533
166k
    fn decode_literal<'a, R: io::BufRead>(
534
166k
        &mut self,
535
166k
        rangecoder: &mut rangecoder::RangeDecoder<'a, R>,
536
166k
        update: bool,
537
166k
    ) -> error::Result<u8> {
538
166k
        let def_prev_byte = 0u8;
539
166k
        let prev_byte = self.output.last_or(def_prev_byte) as usize;
540
541
166k
        let mut result: usize = 1;
542
166k
        let lit_state =
543
166k
            ((self.output.len() & ((1 << self.lp) - 1)) << self.lc) + (prev_byte >> (8 - self.lc));
544
166k
        let probs = &mut self.literal_probs[lit_state];
545
546
166k
        if self.state >= 7 {
547
44.4k
            let mut match_byte = self.output.last_n(self.rep[0] + 1)? as usize;
548
549
94.8k
            while result < 0x100 {
550
93.8k
                let match_bit = (match_byte >> 7) & 1;
551
93.8k
                match_byte <<= 1;
552
93.8k
                let bit = rangecoder
553
93.8k
                    .decode_bit(&mut probs[((1 + match_bit) << 8) + result], update)?
554
                    as usize;
555
93.3k
                result = (result << 1) ^ bit;
556
93.3k
                if match_bit != bit {
557
42.8k
                    break;
558
50.4k
                }
559
            }
560
121k
        }
561
562
1.35M
        while result < 0x100 {
563
1.20M
            result = (result << 1) ^ (rangecoder.decode_bit(&mut probs[result], update)? as usize);
564
        }
565
566
152k
        Ok((result - 0x100) as u8)
567
166k
    }
<lzma_rs::decode::lzma::DecoderState<suricata_htp::decompressors::BlockingCursor, lzma_rs::decode::lzbuffer::LzCircularBuffer<suricata_htp::decompressors::BlockingCursor>>>::decode_literal::<&mut std::io::cursor::Cursor<&[u8]>>
Line
Count
Source
533
1.09M
    fn decode_literal<'a, R: io::BufRead>(
534
1.09M
        &mut self,
535
1.09M
        rangecoder: &mut rangecoder::RangeDecoder<'a, R>,
536
1.09M
        update: bool,
537
1.09M
    ) -> error::Result<u8> {
538
1.09M
        let def_prev_byte = 0u8;
539
1.09M
        let prev_byte = self.output.last_or(def_prev_byte) as usize;
540
541
1.09M
        let mut result: usize = 1;
542
1.09M
        let lit_state =
543
1.09M
            ((self.output.len() & ((1 << self.lp) - 1)) << self.lc) + (prev_byte >> (8 - self.lc));
544
1.09M
        let probs = &mut self.literal_probs[lit_state];
545
546
1.09M
        if self.state >= 7 {
547
31.9k
            let mut match_byte = self.output.last_n(self.rep[0] + 1)? as usize;
548
549
62.5k
            while result < 0x100 {
550
62.0k
                let match_bit = (match_byte >> 7) & 1;
551
62.0k
                match_byte <<= 1;
552
62.0k
                let bit = rangecoder
553
62.0k
                    .decode_bit(&mut probs[((1 + match_bit) << 8) + result], update)?
554
                    as usize;
555
62.0k
                result = (result << 1) ^ bit;
556
62.0k
                if match_bit != bit {
557
31.4k
                    break;
558
30.6k
                }
559
            }
560
1.06M
        }
561
562
9.79M
        while result < 0x100 {
563
8.70M
            result = (result << 1) ^ (rangecoder.decode_bit(&mut probs[result], update)? as usize);
564
        }
565
566
1.09M
        Ok((result - 0x100) as u8)
567
1.09M
    }
Unexecuted instantiation: <lzma_rs::decode::lzma::DecoderState<_, _>>::decode_literal::<_>
Unexecuted instantiation: <lzma_rs::decode::lzma::DecoderState<std::io::cursor::Cursor<&mut [u8]>, lzma_rs::decode::lzbuffer::LzCircularBuffer<std::io::cursor::Cursor<&mut [u8]>>>>::decode_literal::<std::io::cursor::Cursor<&[u8]>>
Unexecuted instantiation: <lzma_rs::decode::lzma::DecoderState<std::io::cursor::Cursor<&mut [u8]>, lzma_rs::decode::lzbuffer::LzCircularBuffer<std::io::cursor::Cursor<&mut [u8]>>>>::decode_literal::<&mut std::io::cursor::Cursor<&[u8]>>
568
569
93.8k
    fn decode_distance<'a, R: io::BufRead>(
570
93.8k
        &mut self,
571
93.8k
        rangecoder: &mut rangecoder::RangeDecoder<'a, R>,
572
93.8k
        length: usize,
573
93.8k
        update: bool,
574
93.8k
    ) -> error::Result<usize> {
575
93.8k
        let len_state = if length > 3 { 3 } else { length };
576
577
93.8k
        let pos_slot = self.pos_slot_decoder[len_state].parse(rangecoder, update)? as usize;
578
89.4k
        if pos_slot < 4 {
579
15.4k
            return Ok(pos_slot);
580
74.0k
        }
581
582
74.0k
        let num_direct_bits = (pos_slot >> 1) - 1;
583
74.0k
        let mut result = (2 ^ (pos_slot & 1)) << num_direct_bits;
584
585
74.0k
        if pos_slot < 14 {
586
15.7k
            result += rangecoder.parse_reverse_bit_tree(
587
15.7k
                num_direct_bits,
588
15.7k
                &mut self.pos_decoders,
589
15.7k
                result - pos_slot,
590
15.7k
                update,
591
1.28k
            )? as usize;
592
        } else {
593
58.3k
            result += (rangecoder.get(num_direct_bits - 4)? as usize) << 4;
594
53.6k
            result += self.align_decoder.parse_reverse(rangecoder, update)? as usize;
595
        }
596
597
66.1k
        Ok(result)
598
93.8k
    }
Unexecuted instantiation: <lzma_rs::decode::lzma::DecoderState<std::io::cursor::Cursor<&mut [u8]>, lzma_rs::decode::lzbuffer::LzCircularBuffer<std::io::cursor::Cursor<&mut [u8]>>>>::decode_distance::<std::io::cursor::Cursor<&[u8]>>
Unexecuted instantiation: <lzma_rs::decode::lzma::DecoderState<std::io::cursor::Cursor<&mut [u8]>, lzma_rs::decode::lzbuffer::LzCircularBuffer<std::io::cursor::Cursor<&mut [u8]>>>>::decode_distance::<&mut std::io::cursor::Cursor<&[u8]>>
<lzma_rs::decode::lzma::DecoderState<suricata_htp::decompressors::BlockingCursor, lzma_rs::decode::lzbuffer::LzCircularBuffer<suricata_htp::decompressors::BlockingCursor>>>::decode_distance::<std::io::cursor::Cursor<&[u8]>>
Line
Count
Source
569
59.8k
    fn decode_distance<'a, R: io::BufRead>(
570
59.8k
        &mut self,
571
59.8k
        rangecoder: &mut rangecoder::RangeDecoder<'a, R>,
572
59.8k
        length: usize,
573
59.8k
        update: bool,
574
59.8k
    ) -> error::Result<usize> {
575
59.8k
        let len_state = if length > 3 { 3 } else { length };
576
577
59.8k
        let pos_slot = self.pos_slot_decoder[len_state].parse(rangecoder, update)? as usize;
578
55.5k
        if pos_slot < 4 {
579
7.54k
            return Ok(pos_slot);
580
47.9k
        }
581
582
47.9k
        let num_direct_bits = (pos_slot >> 1) - 1;
583
47.9k
        let mut result = (2 ^ (pos_slot & 1)) << num_direct_bits;
584
585
47.9k
        if pos_slot < 14 {
586
10.5k
            result += rangecoder.parse_reverse_bit_tree(
587
10.5k
                num_direct_bits,
588
10.5k
                &mut self.pos_decoders,
589
10.5k
                result - pos_slot,
590
10.5k
                update,
591
1.28k
            )? as usize;
592
        } else {
593
37.4k
            result += (rangecoder.get(num_direct_bits - 4)? as usize) << 4;
594
32.7k
            result += self.align_decoder.parse_reverse(rangecoder, update)? as usize;
595
        }
596
597
40.0k
        Ok(result)
598
59.8k
    }
<lzma_rs::decode::lzma::DecoderState<suricata_htp::decompressors::BlockingCursor, lzma_rs::decode::lzbuffer::LzCircularBuffer<suricata_htp::decompressors::BlockingCursor>>>::decode_distance::<&mut std::io::cursor::Cursor<&[u8]>>
Line
Count
Source
569
33.9k
    fn decode_distance<'a, R: io::BufRead>(
570
33.9k
        &mut self,
571
33.9k
        rangecoder: &mut rangecoder::RangeDecoder<'a, R>,
572
33.9k
        length: usize,
573
33.9k
        update: bool,
574
33.9k
    ) -> error::Result<usize> {
575
33.9k
        let len_state = if length > 3 { 3 } else { length };
576
577
33.9k
        let pos_slot = self.pos_slot_decoder[len_state].parse(rangecoder, update)? as usize;
578
33.9k
        if pos_slot < 4 {
579
7.90k
            return Ok(pos_slot);
580
26.0k
        }
581
582
26.0k
        let num_direct_bits = (pos_slot >> 1) - 1;
583
26.0k
        let mut result = (2 ^ (pos_slot & 1)) << num_direct_bits;
584
585
26.0k
        if pos_slot < 14 {
586
5.16k
            result += rangecoder.parse_reverse_bit_tree(
587
5.16k
                num_direct_bits,
588
5.16k
                &mut self.pos_decoders,
589
5.16k
                result - pos_slot,
590
5.16k
                update,
591
0
            )? as usize;
592
        } else {
593
20.9k
            result += (rangecoder.get(num_direct_bits - 4)? as usize) << 4;
594
20.9k
            result += self.align_decoder.parse_reverse(rangecoder, update)? as usize;
595
        }
596
597
26.0k
        Ok(result)
598
33.9k
    }
Unexecuted instantiation: <lzma_rs::decode::lzma::DecoderState<_, _>>::decode_distance::<_>
Unexecuted instantiation: <lzma_rs::decode::lzma::DecoderState<std::io::cursor::Cursor<&mut [u8]>, lzma_rs::decode::lzbuffer::LzCircularBuffer<std::io::cursor::Cursor<&mut [u8]>>>>::decode_distance::<std::io::cursor::Cursor<&[u8]>>
Unexecuted instantiation: <lzma_rs::decode::lzma::DecoderState<std::io::cursor::Cursor<&mut [u8]>, lzma_rs::decode::lzbuffer::LzCircularBuffer<std::io::cursor::Cursor<&mut [u8]>>>>::decode_distance::<&mut std::io::cursor::Cursor<&[u8]>>
599
}