pelite/error.rs
1/*!
2Errors and Results.
3*/
4
5use std::{fmt, result, str};
6
7#[cfg(feature = "std")]
8use std::error;
9
10/// Errors while parsing the PE binary.
11#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
12#[cfg_attr(feature = "serde", derive(::serde::Serialize))]
13pub enum Error {
14 /// Null address.
15 Null,
16 /// Out of bounds.
17 ///
18 /// Catch-all for bounds check errors.
19 Bounds,
20 /// Data is not available.
21 ///
22 /// Can happen when referencing data in `PeFile` instances.
23 ///
24 /// Sections can be shorter than stored on disk, the remaining bytes will default to zeroes when loaded by the system.
25 /// Since these zeroes would just be a waste of space, they are not present in the binaries on disk.
26 /// This error happens when attempting to get a reference to such zero filled data.
27 ZeroFill,
28 /// Data is not available.
29 ///
30 /// Can happen when referencing data in `PeView` instances.
31 ///
32 /// Sections can have excess in their raw data which won't be mapped when loaded by the system.
33 /// This error happens when attempting to get a reference to such unmapped raw data.
34 /// Sometimes this kind of excess is called an overlay.
35 Unmapped,
36 /// Address is misaligned.
37 Misaligned,
38 /// Expected magic number does not match.
39 BadMagic,
40 /// Trying to load a PE32 file with a PE32+ parser or vice versa.
41 PeMagic,
42 /// Sanity check failed.
43 ///
44 /// Some value was so far outside its typical range, while not technically incorrect, probably indicating something went wrong.
45 /// If this error is encountered legitimately, create an issue or file a PR to relax the artificial restrictions.
46 Insanity,
47 /// Invalid data.
48 ///
49 /// Structured data was found which simply isn't valid.
50 /// Catch-all for errors which don't fall under other errors.
51 Invalid,
52 /// Overflow error.
53 ///
54 /// Catch-all for overflow and underflow errors.
55 Overflow,
56 /// Encoding error.
57 ///
58 /// Catch-all for string related errors such as lacking a nul terminator.
59 Encoding,
60 /// Aliasing error.
61 ///
62 /// Request cannot be fulfilled because it would alias with an existing borrow.
63 Aliasing,
64}
65
66impl From<str::Utf8Error> for Error {
67 fn from(_err: str::Utf8Error) -> Error {
68 Error::Encoding
69 }
70}
71
72impl Error {
73 /// Returns if the error variant is Null.
74 ///
75 /// Useful in match guards where `Null` should be handled as a non-error case.
76 ///
77 /// ```
78 /// fn with_default(result: pelite::Result<i32>) -> pelite::Result<i32> {
79 /// let i = match result {
80 /// Ok(i) => i,
81 /// // Avoids a more verbose comparison with pelite::Error::Null
82 /// Err(err) if err.is_null() => 0,
83 /// Err(err) => return Err(err),
84 /// };
85 /// Ok(i)
86 /// }
87 ///
88 /// assert_eq!(with_default(Err(pelite::Error::Null)), Ok(0));
89 /// ```
90 pub fn is_null(self) -> bool {
91 self == Error::Null
92 }
93
94 /// Returns a simple string representation of the error.
95 pub fn to_str(self) -> &'static str {
96 match self {
97 Error::Null => "null address reference",
98 Error::Bounds => "bounds check failed",
99 Error::ZeroFill => "zero filled data reference",
100 Error::Unmapped => "overlay data reference",
101 Error::Misaligned => "address misaligned",
102 Error::BadMagic => "unknown magic number",
103 Error::PeMagic => "try again with correct parser",
104 Error::Insanity => "data insanity",
105 Error::Invalid => "invalid data",
106 Error::Overflow => "overflow error",
107 Error::Encoding => "encoding error",
108 Error::Aliasing => "aliasing error",
109 }
110 }
111}
112
113impl fmt::Display for Error {
114 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
115 f.write_str(self.to_str())
116 }
117}
118
119#[cfg(feature = "std")]
120impl error::Error for Error {
121 fn description(&self) -> &str {
122 self.to_str()
123 }
124}
125
126/// Specialized `Result` type for PE errors.
127pub type Result<T> = result::Result<T, Error>;