Skip to content

Commit 0b67f37

Browse files
cgzonesetke
authored andcommitted
Improve output for unsupported file types
Print actual magic value on error. Print type of object for not implemented ones. Simplify error forwarding by using `?`.
1 parent 96ab8cd commit 0b67f37

File tree

1 file changed

+96
-71
lines changed

1 file changed

+96
-71
lines changed

src/main.rs

Lines changed: 96 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use sysinfo::{
2020
};
2121

2222
use std::path::{Path, PathBuf};
23-
use std::{env, fs, io, process};
23+
use std::{env, fmt, fs, process};
2424

2525
#[cfg(feature = "color")]
2626
use colored::Colorize;
@@ -123,84 +123,109 @@ fn print_process_results(processes: &Processes, settings: &output::Settings) {
123123
}
124124
}
125125

126-
fn parse(file: &Path) -> Result<Vec<Binary>, Error> {
127-
let fp = fs::File::open(file);
128-
if let Err(err) = fp {
129-
return Err(Error::IO(err));
130-
}
131-
if let Ok(buffer) = unsafe { Mmap::map(&fp.unwrap()) } {
132-
match Object::parse(&buffer)? {
133-
#[cfg(feature = "elf")]
134-
Object::Elf(elf) => {
135-
let results = elf::CheckSecResults::parse(&elf);
136-
let bin_type =
137-
if elf.is_64 { BinType::Elf64 } else { BinType::Elf32 };
138-
return Ok(vec![Binary::new(
139-
bin_type,
140-
file.display().to_string(),
141-
BinSpecificProperties::Elf(results),
142-
)]);
126+
enum ParseError {
127+
Goblin(goblin::error::Error),
128+
IO(std::io::Error),
129+
Unimplemented(&'static str),
130+
}
131+
132+
impl fmt::Display for ParseError {
133+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
134+
match self {
135+
Self::Goblin(e) => e.fmt(f),
136+
Self::IO(e) => e.fmt(f),
137+
Self::Unimplemented(str) => {
138+
write!(f, "Support for files of type {} not implemented", str)
143139
}
144-
#[cfg(feature = "pe")]
145-
Object::PE(pe) => {
146-
let results = pe::CheckSecResults::parse(&pe, &buffer);
147-
let bin_type =
148-
if pe.is_64 { BinType::PE64 } else { BinType::PE32 };
149-
return Ok(vec![Binary::new(
140+
}
141+
}
142+
}
143+
144+
impl From<goblin::error::Error> for ParseError {
145+
fn from(err: goblin::error::Error) -> ParseError {
146+
ParseError::Goblin(err)
147+
}
148+
}
149+
150+
impl From<std::io::Error> for ParseError {
151+
fn from(err: std::io::Error) -> ParseError {
152+
ParseError::IO(err)
153+
}
154+
}
155+
156+
fn parse(file: &Path) -> Result<Vec<Binary>, ParseError> {
157+
let fp = fs::File::open(file)?;
158+
let buffer = unsafe { Mmap::map(&fp)? };
159+
match Object::parse(&buffer)? {
160+
#[cfg(feature = "elf")]
161+
Object::Elf(elf) => {
162+
let results = elf::CheckSecResults::parse(&elf);
163+
let bin_type =
164+
if elf.is_64 { BinType::Elf64 } else { BinType::Elf32 };
165+
Ok(vec![Binary::new(
166+
bin_type,
167+
file.display().to_string(),
168+
BinSpecificProperties::Elf(results),
169+
)])
170+
}
171+
#[cfg(feature = "pe")]
172+
Object::PE(pe) => {
173+
let results = pe::CheckSecResults::parse(&pe, &buffer);
174+
let bin_type =
175+
if pe.is_64 { BinType::PE64 } else { BinType::PE32 };
176+
Ok(vec![Binary::new(
177+
bin_type,
178+
file.display().to_string(),
179+
BinSpecificProperties::PE(results),
180+
)])
181+
}
182+
#[cfg(feature = "macho")]
183+
Object::Mach(mach) => match mach {
184+
Mach::Binary(macho) => {
185+
let results = macho::CheckSecResults::parse(&macho);
186+
let bin_type = if macho.is_64 {
187+
BinType::MachO64
188+
} else {
189+
BinType::MachO32
190+
};
191+
Ok(vec![Binary::new(
150192
bin_type,
151193
file.display().to_string(),
152-
BinSpecificProperties::PE(results),
153-
)]);
194+
BinSpecificProperties::MachO(results),
195+
)])
154196
}
155-
#[cfg(feature = "macho")]
156-
Object::Mach(mach) => match mach {
157-
Mach::Binary(macho) => {
158-
let results = macho::CheckSecResults::parse(&macho);
159-
let bin_type = if macho.is_64 {
160-
BinType::MachO64
161-
} else {
162-
BinType::MachO32
163-
};
164-
return Ok(vec![Binary::new(
165-
bin_type,
166-
file.display().to_string(),
167-
BinSpecificProperties::MachO(results),
168-
)]);
169-
}
170-
Mach::Fat(fatmach) => {
171-
let mut fat_bins: Vec<Binary> = Vec::new();
172-
match fatmach.arches() {
173-
Ok(arches) => {
174-
for (idx, _) in arches.iter().enumerate() {
175-
if let Ok(container) = fatmach.get(idx) {
176-
let results =
177-
macho::CheckSecResults::parse(
178-
&container,
179-
);
180-
let bin_type = if container.is_64 {
181-
BinType::MachO64
182-
} else {
183-
BinType::MachO32
184-
};
185-
fat_bins.push(Binary::new(
186-
bin_type,
187-
file.display().to_string(),
188-
BinSpecificProperties::MachO(results),
189-
));
190-
}
191-
}
192-
}
193-
Err(e) => {
194-
return Err(e);
195-
}
197+
Mach::Fat(fatmach) => {
198+
let mut fat_bins: Vec<Binary> = Vec::new();
199+
for (idx, _) in fatmach.arches()?.iter().enumerate() {
200+
if let Ok(container) = fatmach.get(idx) {
201+
let results =
202+
macho::CheckSecResults::parse(&container);
203+
let bin_type = if container.is_64 {
204+
BinType::MachO64
205+
} else {
206+
BinType::MachO32
207+
};
208+
fat_bins.push(Binary::new(
209+
bin_type,
210+
file.display().to_string(),
211+
BinSpecificProperties::MachO(results),
212+
));
196213
}
197-
return Ok(fat_bins);
198214
}
199-
},
200-
_ => return Err(Error::BadMagic(0)),
215+
Ok(fat_bins)
216+
}
217+
},
218+
#[cfg(not(feature = "elf"))]
219+
Object::Elf(_) => Err(ParseError::Unimplemented("ELF")),
220+
#[cfg(not(feature = "pe"))]
221+
Object::PE(_) => Err(ParseError::Unimplemented("PE")),
222+
#[cfg(not(feature = "macho"))]
223+
Object::Mach(_) => Err(ParseError::Unimplemented("MachO")),
224+
Object::Archive(_) => Err(ParseError::Unimplemented("Unix Archive")),
225+
Object::Unknown(magic) => {
226+
Err(ParseError::Goblin(Error::BadMagic(magic)))
201227
}
202228
}
203-
Err(Error::IO(io::Error::last_os_error()))
204229
}
205230

206231
fn walk(basepath: &Path, settings: &output::Settings) {

0 commit comments

Comments
 (0)