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}