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>;