Skip to content

Commit

Permalink
display file targeted and improve error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
agourlay committed Oct 27, 2024
1 parent 7a489ef commit c3bec21
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 12 deletions.
6 changes: 6 additions & 0 deletions src/finder_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ pub enum FinderError {
StdIoError { e: std::io::Error },
#[error("Invalid zip file error - {message}")]
InvalidZip { message: String },
#[error("File number not found within archive error - '{file_number}'")]
FileNotFoundInArchive { file_number: usize },
#[error("CLI argument error - {message:?}")]
CliArgumentError { message: String },
#[error("CLI argument error ({e})")]
Expand All @@ -20,6 +22,10 @@ impl FinderError {
pub fn invalid_zip_error(message: String) -> Self {
InvalidZip { message }
}

pub fn file_not_found_error(file_number: usize) -> Self {
FinderError::FileNotFoundInArchive { file_number }
}
}

impl From<std::io::Error> for FinderError {
Expand Down
12 changes: 11 additions & 1 deletion src/password_finder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,17 @@ pub fn password_finder(
progress_bar.set_draw_target(draw_target);

// Fail early if the zip file is not valid
let aes_info = validate_zip(file_path, file_number)?;
let validated_zip = validate_zip(file_path, file_number)?;
match &validated_zip.file_name {
Some(file_name) => {
progress_bar.println(format!("Targeting file '{file_name}' within the archive"))
}
None => progress_bar.println(format!(
"Cannot get file name from archive for --fileNumber {file_number}"
)),
}

let aes_info = validated_zip.aes_info;
match &aes_info {
Some(aes_info) => progress_bar.println(format!(
"Archive encrypted with AES{} - expect a long wait time",
Expand Down
41 changes: 30 additions & 11 deletions src/zip_utils.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::finder_errors::FinderError;
use std::fs::File;
use std::path::Path;
use zip::result::ZipError;
use zip::result::ZipError::UnsupportedArchive;

#[derive(Clone, Debug)]
Expand All @@ -25,11 +26,26 @@ impl AesInfo {
}
}

pub struct ValidatedZip {
pub aes_info: Option<AesInfo>,
pub file_name: Option<String>,
}

impl ValidatedZip {
pub fn new(aes_info: Option<AesInfo>, file_name: Option<String>) -> Self {
ValidatedZip {
aes_info,
file_name,
}
}
}

// validate that the zip requires a password
pub fn validate_zip(file_path: &Path, file_number: usize) -> Result<Option<AesInfo>, FinderError> {
pub fn validate_zip(file_path: &Path, file_number: usize) -> Result<ValidatedZip, FinderError> {
let file = File::open(file_path)?;
let mut archive = zip::ZipArchive::new(file)?;
let aes_data = archive.get_aes_verification_key_and_salt(file_number);
let file_name = archive.name_for_index(file_number).map(|s| s.to_string());
let zip_result = archive.by_index(file_number);
match zip_result {
Ok(z) => Err(FinderError::invalid_zip_error(format!(
Expand All @@ -38,17 +54,20 @@ pub fn validate_zip(file_path: &Path, file_number: usize) -> Result<Option<AesIn
z.name()
))),
Err(UnsupportedArchive("Password required to decrypt file")) => {
if let Some(aes_zip_info) = aes_data.expect("Archive validated before-hand") {
let aes_key_length = aes_zip_info.aes_mode.key_length();
let verification_value = aes_zip_info.verification_value;
let salt = aes_zip_info.salt;
Ok(Some(AesInfo::new(aes_key_length, verification_value, salt)))
} else {
Ok(None)
}
let aes_info =
if let Some(aes_zip_info) = aes_data.expect("Archive validated before-hand") {
let aes_key_length = aes_zip_info.aes_mode.key_length();
let verification_value = aes_zip_info.verification_value;
let salt = aes_zip_info.salt;
Some(AesInfo::new(aes_key_length, verification_value, salt))
} else {
None
};
Ok(ValidatedZip::new(aes_info, file_name))
}
Err(e) => Err(FinderError::invalid_zip_error(format!(
"unexpected error while opening archive: {e:?}"
Err(ZipError::FileNotFound) => Err(FinderError::file_not_found_error(file_number)),
Err(other) => Err(FinderError::invalid_zip_error(format!(
"unexpected error while opening archive: {other:?}"
))),
}
}

0 comments on commit c3bec21

Please sign in to comment.