Coverage Report

Created: 2025-02-21 07:11

/rust/registry/src/index.crates.io-6f17d22bba15001f/snap-1.1.1/src/error.rs
Line
Count
Source (jump to first uncovered line)
1
use std::fmt;
2
use std::io;
3
use std::result;
4
5
/// A convenient type alias for `Result<T, snap::Error>`.
6
pub type Result<T> = result::Result<T, Error>;
7
8
/// `IntoInnerError` occurs when consuming an encoder fails.
9
///
10
/// Consuming the encoder causes a flush to happen. If the flush fails, then
11
/// this error is returned, which contains both the original encoder and the
12
/// error that occurred.
13
///
14
/// The type parameter `W` is the unconsumed writer.
15
pub struct IntoInnerError<W> {
16
    wtr: W,
17
    err: io::Error,
18
}
19
20
impl<W> IntoInnerError<W> {
21
0
    pub(crate) fn new(wtr: W, err: io::Error) -> IntoInnerError<W> {
22
0
        IntoInnerError { wtr, err }
23
0
    }
24
25
    /// Returns the error which caused the call to `into_inner` to fail.
26
    ///
27
    /// This error was returned when attempting to flush the internal buffer.
28
0
    pub fn error(&self) -> &io::Error {
29
0
        &self.err
30
0
    }
31
32
    /// Returns the error which caused the call to `into_inner` to fail.
33
    ///
34
    /// This error was returned when attempting to flush the internal buffer.
35
0
    pub fn into_error(self) -> io::Error {
36
0
        self.err
37
0
    }
38
39
    /// Returns the underlying writer which generated the error.
40
    ///
41
    /// The returned value can be used for error recovery, such as
42
    /// re-inspecting the buffer.
43
0
    pub fn into_inner(self) -> W {
44
0
        self.wtr
45
0
    }
46
}
47
48
impl<W: std::any::Any> std::error::Error for IntoInnerError<W> {}
49
50
impl<W> fmt::Display for IntoInnerError<W> {
51
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
52
0
        self.err.fmt(f)
53
0
    }
54
}
55
56
impl<W> fmt::Debug for IntoInnerError<W> {
57
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
58
0
        self.err.fmt(f)
59
0
    }
60
}
61
62
/// Error describes all the possible errors that may occur during Snappy
63
/// compression or decompression.
64
///
65
/// Note that it's unlikely that you'll need to care about the specific error
66
/// reported since all of them indicate a corrupt Snappy data or a limitation
67
/// that cannot be worked around. Therefore,
68
/// `From<snap::Error> for std::io::Error` is provided so that any Snappy
69
/// errors will be converted to a `std::io::Error` automatically when using
70
/// `try!`.
71
#[derive(Clone, Debug)]
72
pub enum Error {
73
    /// This error occurs when the given input is too big. This can happen
74
    /// during compression or decompression.
75
    TooBig {
76
        /// The size of the given input.
77
        given: u64,
78
        /// The maximum allowed size of an input buffer.
79
        max: u64,
80
    },
81
    /// This error occurs when the given buffer is too small to contain the
82
    /// maximum possible compressed bytes or the total number of decompressed
83
    /// bytes.
84
    BufferTooSmall {
85
        /// The size of the given output buffer.
86
        given: u64,
87
        /// The minimum size of the output buffer.
88
        min: u64,
89
    },
90
    /// This error occurs when trying to decompress a zero length buffer.
91
    Empty,
92
    /// This error occurs when an invalid header is found during decompression.
93
    Header,
94
    /// This error occurs when there is a mismatch between the number of
95
    /// decompressed bytes reported in the header and the number of
96
    /// actual decompressed bytes. In this error case, the number of actual
97
    /// decompressed bytes is always less than the number reported in the
98
    /// header.
99
    HeaderMismatch {
100
        /// The total number of decompressed bytes expected (i.e., the header
101
        /// value).
102
        expected_len: u64,
103
        /// The total number of actual decompressed bytes.
104
        got_len: u64,
105
    },
106
    /// This error occurs during decompression when there was a problem
107
    /// reading a literal.
108
    Literal {
109
        /// The expected length of the literal.
110
        len: u64,
111
        /// The number of remaining bytes in the compressed bytes.
112
        src_len: u64,
113
        /// The number of remaining slots in the decompression buffer.
114
        dst_len: u64,
115
    },
116
    /// This error occurs during decompression when there was a problem
117
    /// reading a copy.
118
    CopyRead {
119
        /// The expected length of the copy (as encoded in the compressed
120
        /// bytes).
121
        len: u64,
122
        /// The number of remaining bytes in the compressed bytes.
123
        src_len: u64,
124
    },
125
    /// This error occurs during decompression when there was a problem
126
    /// writing a copy to the decompression buffer.
127
    CopyWrite {
128
        /// The length of the copy (i.e., the total number of bytes to be
129
        /// produced by this copy in the decompression buffer).
130
        len: u64,
131
        /// The number of remaining bytes in the decompression buffer.
132
        dst_len: u64,
133
    },
134
    /// This error occurs during decompression when an invalid copy offset
135
    /// is found. An offset is invalid if it is zero or if it is out of bounds.
136
    Offset {
137
        /// The offset that was read.
138
        offset: u64,
139
        /// The current position in the decompression buffer. If the offset is
140
        /// non-zero, then the offset must be greater than this position.
141
        dst_pos: u64,
142
    },
143
    /// This error occurs when a stream header chunk type was expected but got
144
    /// a different chunk type.
145
    /// This error only occurs when reading a Snappy frame formatted stream.
146
    StreamHeader {
147
        /// The chunk type byte that was read.
148
        byte: u8,
149
    },
150
    /// This error occurs when the magic stream headers bytes do not match
151
    /// what is expected.
152
    /// This error only occurs when reading a Snappy frame formatted stream.
153
    StreamHeaderMismatch {
154
        /// The bytes that were read.
155
        bytes: Vec<u8>,
156
    },
157
    /// This error occurs when an unsupported chunk type is seen.
158
    /// This error only occurs when reading a Snappy frame formatted stream.
159
    UnsupportedChunkType {
160
        /// The chunk type byte that was read.
161
        byte: u8,
162
    },
163
    /// This error occurs when trying to read a chunk with an unexpected or
164
    /// incorrect length when reading a Snappy frame formatted stream.
165
    /// This error only occurs when reading a Snappy frame formatted stream.
166
    UnsupportedChunkLength {
167
        /// The length of the chunk encountered.
168
        len: u64,
169
        /// True when this error occured while reading the stream header.
170
        header: bool,
171
    },
172
    /// This error occurs when a checksum validity check fails.
173
    /// This error only occurs when reading a Snappy frame formatted stream.
174
    Checksum {
175
        /// The expected checksum read from the stream.
176
        expected: u32,
177
        /// The computed checksum.
178
        got: u32,
179
    },
180
}
181
182
impl From<Error> for io::Error {
183
0
    fn from(err: Error) -> io::Error {
184
0
        io::Error::new(io::ErrorKind::Other, err)
185
0
    }
186
}
187
188
impl Eq for Error {}
189
190
impl PartialEq for Error {
191
0
    fn eq(&self, other: &Error) -> bool {
192
        use self::Error::*;
193
0
        match (self, other) {
194
            (
195
0
                &TooBig { given: given1, max: max1 },
196
0
                &TooBig { given: given2, max: max2 },
197
0
            ) => (given1, max1) == (given2, max2),
198
            (
199
0
                &BufferTooSmall { given: given1, min: min1 },
200
0
                &BufferTooSmall { given: given2, min: min2 },
201
0
            ) => (given1, min1) == (given2, min2),
202
0
            (&Empty, &Empty) | (&Header, &Header) => true,
203
            (
204
0
                &HeaderMismatch { expected_len: elen1, got_len: glen1 },
205
0
                &HeaderMismatch { expected_len: elen2, got_len: glen2 },
206
0
            ) => (elen1, glen1) == (elen2, glen2),
207
            (
208
0
                &Literal { len: len1, src_len: src_len1, dst_len: dst_len1 },
209
0
                &Literal { len: len2, src_len: src_len2, dst_len: dst_len2 },
210
0
            ) => (len1, src_len1, dst_len1) == (len2, src_len2, dst_len2),
211
            (
212
0
                &CopyRead { len: len1, src_len: src_len1 },
213
0
                &CopyRead { len: len2, src_len: src_len2 },
214
0
            ) => (len1, src_len1) == (len2, src_len2),
215
            (
216
0
                &CopyWrite { len: len1, dst_len: dst_len1 },
217
0
                &CopyWrite { len: len2, dst_len: dst_len2 },
218
0
            ) => (len1, dst_len1) == (len2, dst_len2),
219
            (
220
0
                &Offset { offset: offset1, dst_pos: dst_pos1 },
221
0
                &Offset { offset: offset2, dst_pos: dst_pos2 },
222
0
            ) => (offset1, dst_pos1) == (offset2, dst_pos2),
223
0
            (&StreamHeader { byte: byte1 }, &StreamHeader { byte: byte2 }) => {
224
0
                byte1 == byte2
225
            }
226
            (
227
0
                &StreamHeaderMismatch { bytes: ref bytes1 },
228
0
                &StreamHeaderMismatch { bytes: ref bytes2 },
229
0
            ) => bytes1 == bytes2,
230
            (
231
0
                &UnsupportedChunkType { byte: byte1 },
232
0
                &UnsupportedChunkType { byte: byte2 },
233
0
            ) => byte1 == byte2,
234
            (
235
0
                &UnsupportedChunkLength { len: len1, header: header1 },
236
0
                &UnsupportedChunkLength { len: len2, header: header2 },
237
0
            ) => (len1, header1) == (len2, header2),
238
            (
239
0
                &Checksum { expected: e1, got: g1 },
240
0
                &Checksum { expected: e2, got: g2 },
241
0
            ) => (e1, g1) == (e2, g2),
242
0
            _ => false,
243
        }
244
0
    }
245
}
246
247
impl std::error::Error for Error {}
248
249
impl fmt::Display for Error {
250
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
251
0
        match *self {
252
0
            Error::TooBig { given, max } => write!(
253
0
                f,
254
0
                "snappy: input buffer (size = {}) is larger than \
255
0
                         allowed (size = {})",
256
0
                given, max
257
0
            ),
258
0
            Error::BufferTooSmall { given, min } => write!(
259
0
                f,
260
0
                "snappy: output buffer (size = {}) is smaller than \
261
0
                         required (size = {})",
262
0
                given, min
263
0
            ),
264
0
            Error::Empty => write!(f, "snappy: corrupt input (empty)"),
265
            Error::Header => {
266
0
                write!(f, "snappy: corrupt input (invalid header)")
267
            }
268
0
            Error::HeaderMismatch { expected_len, got_len } => write!(
269
0
                f,
270
0
                "snappy: corrupt input (header mismatch; expected \
271
0
                         {} decompressed bytes but got {})",
272
0
                expected_len, got_len
273
0
            ),
274
0
            Error::Literal { len, src_len, dst_len } => write!(
275
0
                f,
276
0
                "snappy: corrupt input (expected literal read of \
277
0
                         length {}; remaining src: {}; remaining dst: {})",
278
0
                len, src_len, dst_len
279
0
            ),
280
0
            Error::CopyRead { len, src_len } => write!(
281
0
                f,
282
0
                "snappy: corrupt input (expected copy read of \
283
0
                         length {}; remaining src: {})",
284
0
                len, src_len
285
0
            ),
286
0
            Error::CopyWrite { len, dst_len } => write!(
287
0
                f,
288
0
                "snappy: corrupt input (expected copy write of \
289
0
                         length {}; remaining dst: {})",
290
0
                len, dst_len
291
0
            ),
292
0
            Error::Offset { offset, dst_pos } => write!(
293
0
                f,
294
0
                "snappy: corrupt input (expected valid offset but \
295
0
                         got offset {}; dst position: {})",
296
0
                offset, dst_pos
297
0
            ),
298
0
            Error::StreamHeader { byte } => write!(
299
0
                f,
300
0
                "snappy: corrupt input (expected stream header but \
301
0
                         got unexpected chunk type byte {})",
302
0
                byte
303
0
            ),
304
0
            Error::StreamHeaderMismatch { ref bytes } => write!(
305
0
                f,
306
0
                "snappy: corrupt input (expected sNaPpY stream \
307
0
                         header but got {})",
308
0
                escape(&**bytes)
309
0
            ),
310
0
            Error::UnsupportedChunkType { byte } => write!(
311
0
                f,
312
0
                "snappy: corrupt input (unsupported chunk type: {})",
313
0
                byte
314
0
            ),
315
0
            Error::UnsupportedChunkLength { len, header: false } => write!(
316
0
                f,
317
0
                "snappy: corrupt input \
318
0
                         (unsupported chunk length: {})",
319
0
                len
320
0
            ),
321
0
            Error::UnsupportedChunkLength { len, header: true } => write!(
322
0
                f,
323
0
                "snappy: corrupt input \
324
0
                         (invalid stream header length: {})",
325
0
                len
326
0
            ),
327
0
            Error::Checksum { expected, got } => write!(
328
0
                f,
329
0
                "snappy: corrupt input (bad checksum; \
330
0
                         expected: {}, got: {})",
331
0
                expected, got
332
0
            ),
333
        }
334
0
    }
335
}
336
337
0
fn escape(bytes: &[u8]) -> String {
338
    use std::ascii::escape_default;
339
0
    bytes.iter().flat_map(|&b| escape_default(b)).map(|b| b as char).collect()
340
0
}