Coverage Report

Created: 2025-07-23 07:29

/rust/registry/src/index.crates.io-6f17d22bba15001f/flate2-1.0.35/src/zio.rs
Line
Count
Source (jump to first uncovered line)
1
use std::io;
2
use std::io::prelude::*;
3
use std::mem;
4
5
use crate::{Compress, Decompress, DecompressError, FlushCompress, FlushDecompress, Status};
6
7
#[derive(Debug)]
8
pub struct Writer<W: Write, D: Ops> {
9
    obj: Option<W>,
10
    pub data: D,
11
    buf: Vec<u8>,
12
}
13
14
pub trait Ops {
15
    type Flush: Flush;
16
    fn total_in(&self) -> u64;
17
    fn total_out(&self) -> u64;
18
    fn run(
19
        &mut self,
20
        input: &[u8],
21
        output: &mut [u8],
22
        flush: Self::Flush,
23
    ) -> Result<Status, DecompressError>;
24
    fn run_vec(
25
        &mut self,
26
        input: &[u8],
27
        output: &mut Vec<u8>,
28
        flush: Self::Flush,
29
    ) -> Result<Status, DecompressError>;
30
}
31
32
impl Ops for Compress {
33
    type Flush = FlushCompress;
34
0
    fn total_in(&self) -> u64 {
35
0
        self.total_in()
36
0
    }
37
0
    fn total_out(&self) -> u64 {
38
0
        self.total_out()
39
0
    }
40
0
    fn run(
41
0
        &mut self,
42
0
        input: &[u8],
43
0
        output: &mut [u8],
44
0
        flush: FlushCompress,
45
0
    ) -> Result<Status, DecompressError> {
46
0
        Ok(self.compress(input, output, flush).unwrap())
47
0
    }
48
0
    fn run_vec(
49
0
        &mut self,
50
0
        input: &[u8],
51
0
        output: &mut Vec<u8>,
52
0
        flush: FlushCompress,
53
0
    ) -> Result<Status, DecompressError> {
54
0
        Ok(self.compress_vec(input, output, flush).unwrap())
55
0
    }
56
}
57
58
impl Ops for Decompress {
59
    type Flush = FlushDecompress;
60
2.73M
    fn total_in(&self) -> u64 {
61
2.73M
        self.total_in()
62
2.73M
    }
63
6.79M
    fn total_out(&self) -> u64 {
64
6.79M
        self.total_out()
65
6.79M
    }
66
220k
    fn run(
67
220k
        &mut self,
68
220k
        input: &[u8],
69
220k
        output: &mut [u8],
70
220k
        flush: FlushDecompress,
71
220k
    ) -> Result<Status, DecompressError> {
72
220k
        self.decompress(input, output, flush)
73
220k
    }
74
7.34M
    fn run_vec(
75
7.34M
        &mut self,
76
7.34M
        input: &[u8],
77
7.34M
        output: &mut Vec<u8>,
78
7.34M
        flush: FlushDecompress,
79
7.34M
    ) -> Result<Status, DecompressError> {
80
7.34M
        self.decompress_vec(input, output, flush)
81
7.34M
    }
82
}
83
84
pub trait Flush {
85
    fn none() -> Self;
86
    fn sync() -> Self;
87
    fn finish() -> Self;
88
}
89
90
impl Flush for FlushCompress {
91
0
    fn none() -> Self {
92
0
        FlushCompress::None
93
0
    }
94
95
0
    fn sync() -> Self {
96
0
        FlushCompress::Sync
97
0
    }
98
99
0
    fn finish() -> Self {
100
0
        FlushCompress::Finish
101
0
    }
102
}
103
104
impl Flush for FlushDecompress {
105
4.31M
    fn none() -> Self {
106
4.31M
        FlushDecompress::None
107
4.31M
    }
108
109
2.94M
    fn sync() -> Self {
110
2.94M
        FlushDecompress::Sync
111
2.94M
    }
112
113
315k
    fn finish() -> Self {
114
315k
        FlushDecompress::Finish
115
315k
    }
116
}
117
118
226k
pub fn read<R, D>(obj: &mut R, data: &mut D, dst: &mut [u8]) -> io::Result<usize>
119
226k
where
120
226k
    R: BufRead,
121
226k
    D: Ops,
122
226k
{
123
    loop {
124
        let (read, consumed, ret, eof);
125
        {
126
229k
            let input = obj.fill_buf()?;
127
220k
            eof = input.is_empty();
128
220k
            let before_out = data.total_out();
129
220k
            let before_in = data.total_in();
130
220k
            let flush = if eof {
131
0
                D::Flush::finish()
132
            } else {
133
220k
                D::Flush::none()
134
            };
135
220k
            ret = data.run(input, dst, flush);
136
220k
            read = (data.total_out() - before_out) as usize;
137
220k
            consumed = (data.total_in() - before_in) as usize;
138
220k
        }
139
220k
        obj.consume(consumed);
140
141
186k
        match ret {
142
186k
            // If we haven't ready any data and we haven't hit EOF yet,
143
186k
            // then we need to keep asking for more data because if we
144
186k
            // return that 0 bytes of data have been read then it will
145
186k
            // be interpreted as EOF.
146
186k
            Ok(Status::Ok | Status::BufError) if read == 0 && !eof && !dst.is_empty() => continue,
147
191k
            Ok(Status::Ok | Status::BufError | Status::StreamEnd) => return Ok(read),
148
149
            Err(..) => {
150
25.7k
                return Err(io::Error::new(
151
25.7k
                    io::ErrorKind::InvalidInput,
152
25.7k
                    "corrupt deflate stream",
153
25.7k
                ))
154
            }
155
        }
156
    }
157
226k
}
flate2::zio::read::<flate2::bufreader::BufReader<suricata::http2::decompression::HTTP2cursor>, flate2::mem::Decompress>
Line
Count
Source
118
226k
pub fn read<R, D>(obj: &mut R, data: &mut D, dst: &mut [u8]) -> io::Result<usize>
119
226k
where
120
226k
    R: BufRead,
121
226k
    D: Ops,
122
226k
{
123
    loop {
124
        let (read, consumed, ret, eof);
125
        {
126
229k
            let input = obj.fill_buf()?;
127
220k
            eof = input.is_empty();
128
220k
            let before_out = data.total_out();
129
220k
            let before_in = data.total_in();
130
220k
            let flush = if eof {
131
0
                D::Flush::finish()
132
            } else {
133
220k
                D::Flush::none()
134
            };
135
220k
            ret = data.run(input, dst, flush);
136
220k
            read = (data.total_out() - before_out) as usize;
137
220k
            consumed = (data.total_in() - before_in) as usize;
138
220k
        }
139
220k
        obj.consume(consumed);
140
141
186k
        match ret {
142
186k
            // If we haven't ready any data and we haven't hit EOF yet,
143
186k
            // then we need to keep asking for more data because if we
144
186k
            // return that 0 bytes of data have been read then it will
145
186k
            // be interpreted as EOF.
146
186k
            Ok(Status::Ok | Status::BufError) if read == 0 && !eof && !dst.is_empty() => continue,
147
191k
            Ok(Status::Ok | Status::BufError | Status::StreamEnd) => return Ok(read),
148
149
            Err(..) => {
150
25.7k
                return Err(io::Error::new(
151
25.7k
                    io::ErrorKind::InvalidInput,
152
25.7k
                    "corrupt deflate stream",
153
25.7k
                ))
154
            }
155
        }
156
    }
157
226k
}
Unexecuted instantiation: flate2::zio::read::<_, _>
158
159
impl<W: Write, D: Ops> Writer<W, D> {
160
289k
    pub fn new(w: W, d: D) -> Writer<W, D> {
161
289k
        Writer {
162
289k
            obj: Some(w),
163
289k
            data: d,
164
289k
            buf: Vec::with_capacity(32 * 1024),
165
289k
        }
166
289k
    }
<flate2::zio::Writer<suricata_htp::decompressors::BlockingCursor, flate2::mem::Decompress>>::new
Line
Count
Source
160
289k
    pub fn new(w: W, d: D) -> Writer<W, D> {
161
289k
        Writer {
162
289k
            obj: Some(w),
163
289k
            data: d,
164
289k
            buf: Vec::with_capacity(32 * 1024),
165
289k
        }
166
289k
    }
Unexecuted instantiation: <flate2::zio::Writer<_, _>>::new
167
168
315k
    pub fn finish(&mut self) -> io::Result<()> {
169
        loop {
170
315k
            self.dump()?;
171
172
315k
            let before = self.data.total_out();
173
315k
            self.data.run_vec(&[], &mut self.buf, D::Flush::finish())?;
174
150k
            if before == self.data.total_out() {
175
150k
                return Ok(());
176
0
            }
177
        }
178
315k
    }
<flate2::zio::Writer<suricata_htp::decompressors::BlockingCursor, flate2::mem::Decompress>>::finish
Line
Count
Source
168
315k
    pub fn finish(&mut self) -> io::Result<()> {
169
        loop {
170
315k
            self.dump()?;
171
172
315k
            let before = self.data.total_out();
173
315k
            self.data.run_vec(&[], &mut self.buf, D::Flush::finish())?;
174
150k
            if before == self.data.total_out() {
175
150k
                return Ok(());
176
0
            }
177
        }
178
315k
    }
Unexecuted instantiation: <flate2::zio::Writer<_, _>>::finish
179
180
0
    pub fn replace(&mut self, w: W) -> W {
181
0
        self.buf.truncate(0);
182
0
        mem::replace(self.get_mut(), w)
183
0
    }
184
185
0
    pub fn get_ref(&self) -> &W {
186
0
        self.obj.as_ref().unwrap()
187
0
    }
188
189
2.96M
    pub fn get_mut(&mut self) -> &mut W {
190
2.96M
        self.obj.as_mut().unwrap()
191
2.96M
    }
Unexecuted instantiation: <flate2::zio::Writer<_, _>>::get_mut
<flate2::zio::Writer<suricata_htp::decompressors::BlockingCursor, flate2::mem::Decompress>>::get_mut
Line
Count
Source
189
2.96M
    pub fn get_mut(&mut self) -> &mut W {
190
2.96M
        self.obj.as_mut().unwrap()
191
2.96M
    }
192
193
    // Note that this should only be called if the outer object is just about
194
    // to be consumed!
195
    //
196
    // (e.g. an implementation of `into_inner`)
197
14.0k
    pub fn take_inner(&mut self) -> W {
198
14.0k
        self.obj.take().unwrap()
199
14.0k
    }
<flate2::zio::Writer<suricata_htp::decompressors::BlockingCursor, flate2::mem::Decompress>>::take_inner
Line
Count
Source
197
14.0k
    pub fn take_inner(&mut self) -> W {
198
14.0k
        self.obj.take().unwrap()
199
14.0k
    }
Unexecuted instantiation: <flate2::zio::Writer<_, _>>::take_inner
200
201
0
    pub fn is_present(&self) -> bool {
202
0
        self.obj.is_some()
203
0
    }
204
205
    // Returns total written bytes and status of underlying codec
206
1.14M
    pub(crate) fn write_with_status(&mut self, buf: &[u8]) -> io::Result<(usize, Status)> {
207
        // miniz isn't guaranteed to actually write any of the buffer provided,
208
        // it may be in a flushing mode where it's just giving us data before
209
        // we're actually giving it any data. We don't want to spuriously return
210
        // `Ok(0)` when possible as it will cause calls to write_all() to fail.
211
        // As a result we execute this in a loop to ensure that we try our
212
        // darndest to write the data.
213
        loop {
214
1.14M
            self.dump()?;
215
216
1.14M
            let before_in = self.data.total_in();
217
1.14M
            let ret = self.data.run_vec(buf, &mut self.buf, D::Flush::none());
218
1.14M
            let written = (self.data.total_in() - before_in) as usize;
219
1.14M
            let is_stream_end = matches!(ret, Ok(Status::StreamEnd));
220
221
1.14M
            if !buf.is_empty() && written == 0 && ret.is_ok() && !is_stream_end {
222
0
                continue;
223
1.14M
            }
224
1.14M
            return match ret {
225
992k
                Ok(st) => match st {
226
992k
                    Status::Ok | Status::BufError | Status::StreamEnd => Ok((written, st)),
227
                },
228
154k
                Err(..) => Err(io::Error::new(
229
154k
                    io::ErrorKind::InvalidInput,
230
154k
                    "corrupt deflate stream",
231
154k
                )),
232
            };
233
        }
234
1.14M
    }
<flate2::zio::Writer<suricata_htp::decompressors::BlockingCursor, flate2::mem::Decompress>>::write_with_status
Line
Count
Source
206
1.14M
    pub(crate) fn write_with_status(&mut self, buf: &[u8]) -> io::Result<(usize, Status)> {
207
        // miniz isn't guaranteed to actually write any of the buffer provided,
208
        // it may be in a flushing mode where it's just giving us data before
209
        // we're actually giving it any data. We don't want to spuriously return
210
        // `Ok(0)` when possible as it will cause calls to write_all() to fail.
211
        // As a result we execute this in a loop to ensure that we try our
212
        // darndest to write the data.
213
        loop {
214
1.14M
            self.dump()?;
215
216
1.14M
            let before_in = self.data.total_in();
217
1.14M
            let ret = self.data.run_vec(buf, &mut self.buf, D::Flush::none());
218
1.14M
            let written = (self.data.total_in() - before_in) as usize;
219
1.14M
            let is_stream_end = matches!(ret, Ok(Status::StreamEnd));
220
221
1.14M
            if !buf.is_empty() && written == 0 && ret.is_ok() && !is_stream_end {
222
0
                continue;
223
1.14M
            }
224
1.14M
            return match ret {
225
992k
                Ok(st) => match st {
226
992k
                    Status::Ok | Status::BufError | Status::StreamEnd => Ok((written, st)),
227
                },
228
154k
                Err(..) => Err(io::Error::new(
229
154k
                    io::ErrorKind::InvalidInput,
230
154k
                    "corrupt deflate stream",
231
154k
                )),
232
            };
233
        }
234
1.14M
    }
Unexecuted instantiation: <flate2::zio::Writer<_, _>>::write_with_status
235
236
4.40M
    fn dump(&mut self) -> io::Result<()> {
237
        // TODO: should manage this buffer not with `drain` but probably more of
238
        // a deque-like strategy.
239
5.11M
        while !self.buf.is_empty() {
240
708k
            let n = self.obj.as_mut().unwrap().write(&self.buf)?;
241
708k
            if n == 0 {
242
0
                return Err(io::ErrorKind::WriteZero.into());
243
708k
            }
244
708k
            self.buf.drain(..n);
245
        }
246
4.40M
        Ok(())
247
4.40M
    }
<flate2::zio::Writer<suricata_htp::decompressors::BlockingCursor, flate2::mem::Decompress>>::dump
Line
Count
Source
236
4.40M
    fn dump(&mut self) -> io::Result<()> {
237
        // TODO: should manage this buffer not with `drain` but probably more of
238
        // a deque-like strategy.
239
5.11M
        while !self.buf.is_empty() {
240
708k
            let n = self.obj.as_mut().unwrap().write(&self.buf)?;
241
708k
            if n == 0 {
242
0
                return Err(io::ErrorKind::WriteZero.into());
243
708k
            }
244
708k
            self.buf.drain(..n);
245
        }
246
4.40M
        Ok(())
247
4.40M
    }
Unexecuted instantiation: <flate2::zio::Writer<_, _>>::dump
248
}
249
250
impl<W: Write, D: Ops> Write for Writer<W, D> {
251
1.14M
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
252
1.14M
        self.write_with_status(buf).map(|res| res.0)
Unexecuted instantiation: <flate2::zio::Writer<_, _> as std::io::Write>::write::{closure#0}
<flate2::zio::Writer<suricata_htp::decompressors::BlockingCursor, flate2::mem::Decompress> as std::io::Write>::write::{closure#0}
Line
Count
Source
252
992k
        self.write_with_status(buf).map(|res| res.0)
253
1.14M
    }
Unexecuted instantiation: <flate2::zio::Writer<_, _> as std::io::Write>::write
<flate2::zio::Writer<suricata_htp::decompressors::BlockingCursor, flate2::mem::Decompress> as std::io::Write>::write
Line
Count
Source
251
1.14M
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
252
1.14M
        self.write_with_status(buf).map(|res| res.0)
253
1.14M
    }
254
255
2.94M
    fn flush(&mut self) -> io::Result<()> {
256
2.94M
        self.data
257
2.94M
            .run_vec(&[], &mut self.buf, D::Flush::sync())
258
2.94M
            .unwrap();
259
260
        // Unfortunately miniz doesn't actually tell us when we're done with
261
        // pulling out all the data from the internal stream. To remedy this we
262
        // have to continually ask the stream for more memory until it doesn't
263
        // give us a chunk of memory the same size as our own internal buffer,
264
        // at which point we assume it's reached the end.
265
        loop {
266
2.94M
            self.dump()?;
267
2.94M
            let before = self.data.total_out();
268
2.94M
            self.data
269
2.94M
                .run_vec(&[], &mut self.buf, D::Flush::none())
270
2.94M
                .unwrap();
271
2.94M
            if before == self.data.total_out() {
272
2.94M
                break;
273
21
            }
274
        }
275
276
2.94M
        self.obj.as_mut().unwrap().flush()
277
2.94M
    }
<flate2::zio::Writer<suricata_htp::decompressors::BlockingCursor, flate2::mem::Decompress> as std::io::Write>::flush
Line
Count
Source
255
2.94M
    fn flush(&mut self) -> io::Result<()> {
256
2.94M
        self.data
257
2.94M
            .run_vec(&[], &mut self.buf, D::Flush::sync())
258
2.94M
            .unwrap();
259
260
        // Unfortunately miniz doesn't actually tell us when we're done with
261
        // pulling out all the data from the internal stream. To remedy this we
262
        // have to continually ask the stream for more memory until it doesn't
263
        // give us a chunk of memory the same size as our own internal buffer,
264
        // at which point we assume it's reached the end.
265
        loop {
266
2.94M
            self.dump()?;
267
2.94M
            let before = self.data.total_out();
268
2.94M
            self.data
269
2.94M
                .run_vec(&[], &mut self.buf, D::Flush::none())
270
2.94M
                .unwrap();
271
2.94M
            if before == self.data.total_out() {
272
2.94M
                break;
273
21
            }
274
        }
275
276
2.94M
        self.obj.as_mut().unwrap().flush()
277
2.94M
    }
Unexecuted instantiation: <flate2::zio::Writer<_, _> as std::io::Write>::flush
278
}
279
280
impl<W: Write, D: Ops> Drop for Writer<W, D> {
281
289k
    fn drop(&mut self) {
282
289k
        if self.obj.is_some() {
283
275k
            let _ = self.finish();
284
275k
        }
285
289k
    }
<flate2::zio::Writer<suricata_htp::decompressors::BlockingCursor, flate2::mem::Decompress> as core::ops::drop::Drop>::drop
Line
Count
Source
281
289k
    fn drop(&mut self) {
282
289k
        if self.obj.is_some() {
283
275k
            let _ = self.finish();
284
275k
        }
285
289k
    }
Unexecuted instantiation: <flate2::zio::Writer<_, _> as core::ops::drop::Drop>::drop
286
}