Skip to content

Commit

Permalink
Can detect malformed ddrescue files where the disk map is not contigu…
Browse files Browse the repository at this point in the history
…ous or is overlapping
  • Loading branch information
CKingX committed May 9, 2022
1 parent 97d2bf9 commit 78cc14d
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 1 deletion.
8 changes: 7 additions & 1 deletion src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use std::io::Write;
use std::{env, io::ErrorKind, process};
use termcolor::{self, Color, ColorChoice, ColorSpec, StandardStream, WriteColor};

/// Represents all the exit codes of the program with 0 being success and the rest being errors
#[repr(i32)]
pub enum ExitCode {
FileError = 1,
Expand All @@ -15,7 +16,6 @@ pub enum ExitCode {
OOMError = 6,
ParseError = 7,
UnmountError = 8,
/// Sector Size not a multiple of 512
SectorSizeError = 9,
UnknownError = 10,
}
Expand Down Expand Up @@ -44,6 +44,12 @@ pub const NO_DEVICE_UNMOUNT_ERROR: &str = "Unmount error: Unable to find device"
pub const UNMOUNT_ERROR: &str = "Unable to unmount device";
pub const FILE_NOT_FOUND_ERROR: &str = "Unable to find";
pub const SECTOR_SIZE_ERROR: &str = "Sector size is not a multiple of 512";
pub const CONTIGUOUS_ERROR: &str = "ddrescue map of disk is not contiguous";

pub fn contiguous_error() -> ! {
print_error(CONTIGUOUS_ERROR);
process::exit(ExitCode::ParseError as i32);
}

pub fn file_not_found(filetype: FileType) -> String {
format!("{FILE_NOT_FOUND_ERROR} {}", filetype.to_string())
Expand Down
10 changes: 10 additions & 0 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::error;
use std::{ffi::OsString, fmt::Write, fs};

/// Parses ddrescue map file to dmsetup table
/// Structure of map file can be found [here](https://www.gnu.org/software/ddrescue/manual/ddrescue_manual.html#Mapfile-structure)
pub fn parse_map(map_path: &OsString, device_name: &str) -> String {
let mut output = String::new();
let contents = fs::read_to_string(map_path.clone()).unwrap_or_else(|error| {
Expand All @@ -18,6 +19,8 @@ pub fn parse_map(map_path: &OsString, device_name: &str) -> String {
.filter(|s| !s.is_empty() && !s.contains('#'))
.skip(1);

let mut prev_entry = 0;

for line in file_line {
let mut map_line = line.split_ascii_whitespace();
let pos_string = map_line.next().expect(error::PARSE_ERROR).to_string();
Expand All @@ -41,6 +44,13 @@ pub fn parse_map(map_path: &OsString, device_name: &str) -> String {
} else {
error::handle_string_write(writeln!(output, "{}", create_error(pos, size)));
}

// Check if sector is contiguous
if pos != prev_entry {
error::contiguous_error();
} else {
prev_entry = pos + size;
}
}

output
Expand Down

0 comments on commit 78cc14d

Please sign in to comment.