jiff/error/tz/
concatenated.rs

1use crate::error;
2
3// At time of writing, the biggest TZif data file is a few KB. And the
4// index block is tens of KB. So impose a limit that is a couple of orders
5// of magnitude bigger, but still overall pretty small for... some systems.
6// Anyway, I welcome improvements to this heuristic!
7pub(crate) const ALLOC_LIMIT: usize = 10 * 1 << 20;
8
9#[derive(Clone, Debug)]
10pub(crate) enum Error {
11    AllocRequestOverLimit,
12    AllocFailed,
13    AllocOverflow,
14    ExpectedFirstSixBytes,
15    ExpectedIanaName,
16    ExpectedLastByte,
17    #[cfg(test)]
18    ExpectedMoreData,
19    ExpectedVersion,
20    FailedReadData,
21    FailedReadHeader,
22    FailedReadIndex,
23    #[cfg(all(feature = "std", all(not(unix), not(windows))))]
24    FailedSeek,
25    InvalidIndexDataOffsets,
26    InvalidLengthIndexBlock,
27    #[cfg(all(feature = "std", windows))]
28    InvalidOffsetOverflowFile,
29    #[cfg(test)]
30    InvalidOffsetOverflowSlice,
31    #[cfg(test)]
32    InvalidOffsetTooBig,
33}
34
35impl From<Error> for error::Error {
36    #[cold]
37    #[inline(never)]
38    fn from(err: Error) -> error::Error {
39        error::ErrorKind::TzConcatenated(err).into()
40    }
41}
42
43impl error::IntoError for Error {
44    fn into_error(self) -> error::Error {
45        self.into()
46    }
47}
48
49impl core::fmt::Display for Error {
50    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
51        use self::Error::*;
52
53        match *self {
54            AllocRequestOverLimit => write!(
55                f,
56                "attempted to allocate more than {ALLOC_LIMIT} bytes \
57                 while reading concatenated TZif data, which \
58                 exceeds a heuristic limit to prevent huge allocations \
59                 (please file a bug if this error is inappropriate)",
60            ),
61            AllocFailed => f.write_str(
62                "failed to allocate additional room \
63                 for reading concatenated TZif data",
64            ),
65            AllocOverflow => {
66                f.write_str("total allocation length overflowed `usize`")
67            }
68            ExpectedFirstSixBytes => f.write_str(
69                "expected first 6 bytes of concatenated TZif header \
70                 to be `tzdata`",
71            ),
72            ExpectedIanaName => f.write_str(
73                "expected IANA time zone identifier to be valid UTF-8",
74            ),
75            ExpectedLastByte => f.write_str(
76                "expected last byte of concatenated TZif header \
77                 to be `NUL`",
78            ),
79            #[cfg(test)]
80            ExpectedMoreData => f.write_str(
81                "unexpected EOF, expected more bytes based on size \
82                 of caller provided buffer",
83            ),
84            ExpectedVersion => f.write_str(
85                "expected version in concatenated TZif header to \
86                 be valid UTF-8",
87            ),
88            FailedReadData => f.write_str("failed to read TZif data block"),
89            FailedReadHeader => {
90                f.write_str("failed to read concatenated TZif header")
91            }
92            FailedReadIndex => f.write_str("failed to read index block"),
93            #[cfg(all(feature = "std", all(not(unix), not(windows))))]
94            FailedSeek => {
95                f.write_str("failed to seek to offset in `std::fs::File`")
96            }
97            InvalidIndexDataOffsets => f.write_str(
98                "invalid index and data offsets, \
99                 expected index offset to be less than or equal \
100                 to data offset",
101            ),
102            InvalidLengthIndexBlock => {
103                f.write_str("length of index block is not a valid multiple")
104            }
105            #[cfg(all(feature = "std", windows))]
106            InvalidOffsetOverflowFile => f.write_str(
107                "offset overflow when reading from `std::fs::File`",
108            ),
109            #[cfg(test)]
110            InvalidOffsetOverflowSlice => {
111                f.write_str("offset overflowed `usize`")
112            }
113            #[cfg(test)]
114            InvalidOffsetTooBig => {
115                f.write_str("offset too big for given slice of data")
116            }
117        }
118    }
119}