1mod compile;
2
3pub use self::compile::*;
4
5use std::error;
6use std::fmt;
7use std::os::raw::c_int;
8
9use crate::ERROR_CALLBACK_ERROR;
10use crate::ERROR_CORRUPT_FILE;
11use crate::ERROR_COULD_NOT_ATTACH_TO_PROCESS;
12use crate::ERROR_COULD_NOT_MAP_FILE;
13use crate::ERROR_COULD_NOT_OPEN_FILE;
14use crate::ERROR_COULD_NOT_READ_PROCESS_MEMORY;
15use crate::ERROR_INSUFFICIENT_MEMORY;
16use crate::ERROR_INTERNAL_FATAL_ERROR;
17use crate::ERROR_INVALID_FILE;
18use crate::ERROR_SCAN_TIMEOUT;
19use crate::ERROR_SUCCESS;
20use crate::ERROR_SYNTAX_ERROR;
21use crate::ERROR_TOO_MANY_MATCHES;
22use crate::ERROR_UNSUPPORTED_FILE_VERSION;
23
24#[derive(Clone, Copy, Debug, Eq, PartialEq)]
25pub enum Error {
26 CallbackError,
28 CorruptFile,
30 CouldNotAttach,
32 CouldNotMapFile,
34 CouldNotOpenFile,
36 CouldNotReadProcessMemory,
38 InsufficientMemory,
40 InternalFatalError,
42 InvalidFile,
44 ScanTimeout,
46 SyntaxError,
48 TooManyMatches,
50 UnsupportedFileVersion,
52 Unknown(i32),
54}
55
56impl Error {
57 #[deny(unused_variables)]
58 pub fn from_code(code: c_int) -> Result<(), Error> {
59 use self::Error::*;
60
61 if code as u32 == ERROR_SUCCESS {
62 return Ok(());
63 }
64
65 Err(match code as u32 {
66 ERROR_CALLBACK_ERROR => CallbackError,
67 ERROR_CORRUPT_FILE => CorruptFile,
68 ERROR_COULD_NOT_ATTACH_TO_PROCESS => CouldNotAttach,
69 ERROR_COULD_NOT_MAP_FILE => CouldNotMapFile,
70 ERROR_COULD_NOT_OPEN_FILE => CouldNotOpenFile,
71 ERROR_INSUFFICIENT_MEMORY => InsufficientMemory,
72 ERROR_INTERNAL_FATAL_ERROR => InternalFatalError,
73 ERROR_INVALID_FILE => InvalidFile,
74 ERROR_SCAN_TIMEOUT => ScanTimeout,
75 ERROR_SYNTAX_ERROR => SyntaxError,
76 ERROR_TOO_MANY_MATCHES => TooManyMatches,
77 ERROR_UNSUPPORTED_FILE_VERSION => UnsupportedFileVersion,
78 ERROR_COULD_NOT_READ_PROCESS_MEMORY => CouldNotReadProcessMemory,
79 _ => Unknown(code),
80 })
81 }
82}
83
84impl fmt::Display for Error {
85 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
86 f.write_str((*self).into())
87 }
88}
89
90impl error::Error for Error {}
91
92impl From<Error> for &'static str {
93 fn from(error: Error) -> &'static str {
94 use self::Error::*;
95
96 match error {
97 CallbackError => "Callback returned an error",
98 CorruptFile => "Rule file is corrupt",
99 CouldNotAttach => "Could not attach to process",
100 CouldNotMapFile => "File could not be mapped into memory",
101 CouldNotOpenFile => "File could not be opened",
102 CouldNotReadProcessMemory => "Process memory could not be read",
103 InsufficientMemory => "Insufficient memory to complete the operation",
104 InternalFatalError => "Internal fatal error",
105 InvalidFile => "File is not a valid rules file",
106 ScanTimeout => "Timeouted during scan",
107 SyntaxError => "Syntax error in rule",
108 TooManyMatches => "Too many matches",
109 UnsupportedFileVersion => "Rule file version is not supported",
110 Unknown(_) => "Unknown Yara error",
111 }
112 }
113}
114
115#[cfg(test)]
116mod tests {
117 use super::*;
118
119 #[test]
120 fn test_error_from_code() {
121 use super::Error::*;
122
123 assert_eq!(Ok(()), Error::from_code(ERROR_SUCCESS as i32));
124 assert_eq!(
125 Err(InsufficientMemory),
126 Error::from_code(ERROR_INSUFFICIENT_MEMORY as i32)
127 );
128 assert_eq!(
129 Err(ScanTimeout),
130 Error::from_code(ERROR_SCAN_TIMEOUT as i32)
131 );
132 }
133
134 #[test]
135 fn test_to_string() {
136 assert_eq!(
137 "Callback returned an error",
138 Error::CallbackError.to_string()
139 );
140 assert_eq!(
141 "Callback returned an error",
142 Error::CallbackError.to_string()
143 );
144 }
145}