stream_unzip/
error.rs

1use std::{array::TryFromSliceError, error, fmt};
2
3/// Any zip-related error, from invalid archives to encoding problems.
4#[derive(Debug)]
5pub enum Error {
6    /// Not a valid zip file, or a variant that is unsupported.
7    Format(FormatError),
8
9    /// Bad header format
10    BadHeader,
11
12    /// I/O-related error
13    ///
14    /// Only returned by the higher-level API, since
15    /// [ArchiveReader](crate::reader::ArchiveReader) lets you do your own I/O.
16    IO(std::io::Error),
17}
18
19/// Specific zip format errors, mostly due to invalid zip archives but that could also stem from
20/// implementation shortcomings.
21#[derive(Debug)]
22pub enum FormatError {
23    /// The end of central directory record was not found.
24    ///
25    /// This usually indicates that the file being read is not a zip archive.
26    DirectoryEndSignatureNotFound,
27    /// The zip64 end of central directory record could not be parsed.
28    ///
29    /// This is only returned when a zip64 end of central directory *locator* was found,
30    /// so the archive should be zip64, but isn't.
31    Directory64EndRecordInvalid,
32    /// Corrupted/partial zip file: the offset we found for the central directory
33    /// points outside of the current file.
34    DirectoryOffsetPointsOutsideFile,
35    /// The central record is corrupted somewhat.
36    ///
37    /// This can happen when the end of central directory record advertises
38    /// a certain number of files, but we weren't able to read the same number of central directory
39    /// headers.
40    InvalidCentralRecord { expected: u16, actual: u16 },
41    /// An extra field (that we support) was not decoded correctly.
42    ///
43    /// This can indicate an invalid zip archive, or an implementation error in this crate.
44    InvalidExtraField,
45    /// End of central directory record claims an impossible number of file.
46    ///
47    /// Each entry takes a minimum amount of size, so if the overall archive size is smaller than
48    /// claimed_records_count * minimum_entry_size, we know it's not a valid zip file.
49    ImpossibleNumberOfFiles {
50        claimed_records_count: u64,
51        zip_size: u64,
52    },
53    /// The local file header (before the file data) could not be parsed correctly.
54    InvalidLocalHeader,
55    /// The data descriptor (after the file data) could not be parsed correctly.
56    InvalidDataDescriptor,
57    /// The uncompressed size didn't match
58    WrongSize { expected: u64, actual: u64 },
59    /// The CRC-32 checksum didn't match.
60    WrongChecksum { expected: u32, actual: u32 },
61}
62
63impl error::Error for Error {}
64
65impl fmt::Display for Error {
66    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
67        match self {
68            Error::IO(e) => write!(f, "IO error: {}", e),
69            Error::Format(e) => write!(f, "{:#?}", e),
70            Error::BadHeader => write!(f, "Bad header format",),
71        }
72    }
73}
74
75impl From<std::io::Error> for Error {
76    fn from(e: std::io::Error) -> Self {
77        Error::IO(e)
78    }
79}
80
81impl From<FormatError> for Error {
82    fn from(e: FormatError) -> Self {
83        Error::Format(e)
84    }
85}
86
87impl From<Error> for std::io::Error {
88    fn from(val: Error) -> Self {
89        std::io::Error::new(std::io::ErrorKind::Other, val)
90    }
91}
92
93impl From<TryFromSliceError> for Error {
94    fn from(_: TryFromSliceError) -> Self {
95        Error::BadHeader
96    }
97}