Skip to main content

safari_binarycookies/
error.rs

1//! Decode-failure taxonomy for the `.binarycookies` format.
2
3/// Which of the five cookie string components overflowed the size cap.
4#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5#[non_exhaustive]
6pub enum Component {
7    /// The comment region (`commentOffset..domainOffset`).
8    Comment,
9    /// The domain field.
10    Domain,
11    /// The name field.
12    Name,
13    /// The path field.
14    Path,
15    /// The value field.
16    Value,
17}
18
19impl core::fmt::Display for Component {
20    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
21        f.write_str(match self {
22            Self::Comment => "comment",
23            Self::Domain => "domain",
24            Self::Name => "name",
25            Self::Path => "path",
26            Self::Value => "value",
27        })
28    }
29}
30
31/// Errors produced while decoding a `.binarycookies` file.
32///
33/// Every malformed input maps to a variant here; the decoder never panics.
34#[derive(Debug, thiserror::Error)]
35#[non_exhaustive]
36pub enum Error {
37    /// The underlying reader failed; only `from_reader` / `from_path` produce this.
38    #[error("io error: {0}")]
39    Io(#[from] std::io::Error),
40
41    /// The file does not start with the `cook` magic; carries the four bytes found.
42    #[error("invalid signature: {0:?}")]
43    InvalidSignature([u8; 4]),
44
45    /// A page does not start with the `00 00 01 00` tag.
46    #[error("invalid page tag")]
47    InvalidPageTag,
48
49    /// A page header does not end with the `00 00 00 00` marker.
50    #[error("invalid page end")]
51    InvalidPageEnd,
52
53    /// A cookie header does not end with the `00 00 00 00` marker.
54    #[error("invalid cookie header end")]
55    InvalidCookieHeaderEnd,
56
57    /// The input ended before the structure it declares was fully read.
58    #[error("unexpected end of input")]
59    UnexpectedEof,
60
61    /// The declared page count exceeds the hardening cap of 65 536.
62    #[error("page count too large: {0}")]
63    TooManyPages(u32),
64
65    /// The declared per-page cookie count exceeds the hardening cap of 1 048 576.
66    #[error("cookie count too large: {0}")]
67    TooManyCookies(u32),
68
69    /// One of the five cookie components is longer than 4096 bytes.
70    #[error("cookie {component} component too large: {size}")]
71    CookieTooLarge {
72        /// Which component overflowed.
73        component: Component,
74        /// Length of the offending component in bytes.
75        size: u32,
76    },
77
78    /// The five cookie components together exceed 4096 bytes.
79    #[error("cookie total size too large: {0}")]
80    CookieTotalTooLarge(u32),
81
82    /// Cookie string offsets are not monotonically increasing.
83    #[error("malformed cookie offsets")]
84    MalformedOffsets,
85}