mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-29 12:07:46 +00:00
feat(checksum): get rid of the properly_formatted variable
This commit is contained in:
parent
f3763ef190
commit
a0af49f2d8
1 changed files with 30 additions and 48 deletions
|
@ -174,8 +174,6 @@ pub enum ChecksumError {
|
||||||
CombineMultipleAlgorithms,
|
CombineMultipleAlgorithms,
|
||||||
#[error("Needs an algorithm to hash with.\nUse --help for more information.")]
|
#[error("Needs an algorithm to hash with.\nUse --help for more information.")]
|
||||||
NeedAlgorithmToHash,
|
NeedAlgorithmToHash,
|
||||||
#[error("{filename}: no properly formatted checksum lines found")]
|
|
||||||
NoProperlyFormattedChecksumLinesFound { filename: String },
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UError for ChecksumError {
|
impl UError for ChecksumError {
|
||||||
|
@ -241,6 +239,12 @@ fn cksum_output(res: &ChecksumResult, status: bool) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Print a "no properly formatted lines" message in stderr
|
||||||
|
#[inline]
|
||||||
|
fn log_no_properly_formatted(filename: String) {
|
||||||
|
show_error!("{filename}: no properly formatted checksum lines found");
|
||||||
|
}
|
||||||
|
|
||||||
/// Represents the different outcomes that can happen to a file
|
/// Represents the different outcomes that can happen to a file
|
||||||
/// that is being checked.
|
/// that is being checked.
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
@ -442,7 +446,7 @@ fn determine_regex(lines: &[OsString]) -> Option<(Regex, bool)> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extract the expected digest from the checksum string
|
/// Extract the expected digest from the checksum string
|
||||||
fn get_expected_digest_as_hexa_string(caps: &Captures, chosen_regex: &Regex) -> Option<String> {
|
fn get_expected_digest_as_hex_string(caps: &Captures, chosen_regex: &Regex) -> Option<String> {
|
||||||
// Unwraps are safe, ensured by regex.
|
// Unwraps are safe, ensured by regex.
|
||||||
let ck = caps.name("checksum").unwrap().as_bytes();
|
let ck = caps.name("checksum").unwrap().as_bytes();
|
||||||
|
|
||||||
|
@ -528,8 +532,6 @@ fn get_input_file(filename: &OsStr) -> UResult<Box<dyn Read>> {
|
||||||
fn identify_algo_name_and_length(
|
fn identify_algo_name_and_length(
|
||||||
caps: &Captures,
|
caps: &Captures,
|
||||||
algo_name_input: Option<&str>,
|
algo_name_input: Option<&str>,
|
||||||
res: &mut ChecksumResult,
|
|
||||||
properly_formatted: &mut bool,
|
|
||||||
) -> Option<(String, Option<usize>)> {
|
) -> Option<(String, Option<usize>)> {
|
||||||
// When the algo-based format is matched, extract details from regex captures
|
// When the algo-based format is matched, extract details from regex captures
|
||||||
let algorithm = caps
|
let algorithm = caps
|
||||||
|
@ -543,14 +545,11 @@ fn identify_algo_name_and_length(
|
||||||
// (for example SHA1 (f) = d...)
|
// (for example SHA1 (f) = d...)
|
||||||
// Also handle the case cksum -s sm3 but the file contains other formats
|
// Also handle the case cksum -s sm3 but the file contains other formats
|
||||||
if algo_name_input.is_some() && algo_name_input != Some(&algorithm) {
|
if algo_name_input.is_some() && algo_name_input != Some(&algorithm) {
|
||||||
res.bad_format += 1;
|
|
||||||
*properly_formatted = false;
|
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
if !SUPPORTED_ALGORITHMS.contains(&algorithm.as_str()) {
|
if !SUPPORTED_ALGORITHMS.contains(&algorithm.as_str()) {
|
||||||
// Not supported algo, leave early
|
// Not supported algo, leave early
|
||||||
*properly_formatted = false;
|
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -562,7 +561,6 @@ fn identify_algo_name_and_length(
|
||||||
if bits_value % 8 == 0 {
|
if bits_value % 8 == 0 {
|
||||||
Some(Some(bits_value / 8))
|
Some(Some(bits_value / 8))
|
||||||
} else {
|
} else {
|
||||||
*properly_formatted = false;
|
|
||||||
None // Return None to signal a divisibility issue
|
None // Return None to signal a divisibility issue
|
||||||
}
|
}
|
||||||
})?;
|
})?;
|
||||||
|
@ -583,16 +581,12 @@ fn process_checksum_line(
|
||||||
i: usize,
|
i: usize,
|
||||||
chosen_regex: &Regex,
|
chosen_regex: &Regex,
|
||||||
is_algo_based_format: bool,
|
is_algo_based_format: bool,
|
||||||
res: &mut ChecksumResult,
|
|
||||||
cli_algo_name: Option<&str>,
|
cli_algo_name: Option<&str>,
|
||||||
cli_algo_length: Option<usize>,
|
cli_algo_length: Option<usize>,
|
||||||
properly_formatted: &mut bool,
|
|
||||||
opts: ChecksumOptions,
|
opts: ChecksumOptions,
|
||||||
) -> Result<(), LineCheckError> {
|
) -> Result<(), LineCheckError> {
|
||||||
let line_bytes = os_str_as_bytes(line)?;
|
let line_bytes = os_str_as_bytes(line)?;
|
||||||
if let Some(caps) = chosen_regex.captures(line_bytes) {
|
if let Some(caps) = chosen_regex.captures(line_bytes) {
|
||||||
*properly_formatted = true;
|
|
||||||
|
|
||||||
let mut filename_to_check = caps.name("filename").unwrap().as_bytes();
|
let mut filename_to_check = caps.name("filename").unwrap().as_bytes();
|
||||||
|
|
||||||
if filename_to_check.starts_with(b"*")
|
if filename_to_check.starts_with(b"*")
|
||||||
|
@ -603,18 +597,13 @@ fn process_checksum_line(
|
||||||
filename_to_check = &filename_to_check[1..];
|
filename_to_check = &filename_to_check[1..];
|
||||||
}
|
}
|
||||||
|
|
||||||
let expected_checksum = get_expected_digest_as_hexa_string(&caps, chosen_regex).ok_or(
|
let expected_checksum = get_expected_digest_as_hex_string(&caps, chosen_regex)
|
||||||
LineCheckError::UError(Box::new(
|
.ok_or(LineCheckError::ImproperlyFormatted)?;
|
||||||
ChecksumError::NoProperlyFormattedChecksumLinesFound {
|
|
||||||
filename: String::from_utf8_lossy(filename_to_check).to_string(),
|
|
||||||
},
|
|
||||||
)),
|
|
||||||
)?;
|
|
||||||
|
|
||||||
// If the algo_name is provided, we use it, otherwise we try to detect it
|
// If the algo_name is provided, we use it, otherwise we try to detect it
|
||||||
let (algo_name, length) = if is_algo_based_format {
|
let (algo_name, length) = if is_algo_based_format {
|
||||||
identify_algo_name_and_length(&caps, cli_algo_name, res, properly_formatted)
|
identify_algo_name_and_length(&caps, cli_algo_name)
|
||||||
.unwrap_or((String::new(), None))
|
.ok_or(LineCheckError::ImproperlyFormatted)?
|
||||||
} else if let Some(a) = cli_algo_name {
|
} else if let Some(a) = cli_algo_name {
|
||||||
// When a specific algorithm name is input, use it and use the provided bits
|
// When a specific algorithm name is input, use it and use the provided bits
|
||||||
// except when dealing with blake2b, where we will detect the length
|
// except when dealing with blake2b, where we will detect the length
|
||||||
|
@ -628,16 +617,9 @@ fn process_checksum_line(
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Default case if no algorithm is specified and non-algo based format is matched
|
// Default case if no algorithm is specified and non-algo based format is matched
|
||||||
(String::new(), None)
|
return Err(LineCheckError::ImproperlyFormatted);
|
||||||
};
|
};
|
||||||
|
|
||||||
if algo_name.is_empty() {
|
|
||||||
// we haven't been able to detect the algo name. No point to continue
|
|
||||||
*properly_formatted = false;
|
|
||||||
|
|
||||||
// TODO: return error?
|
|
||||||
return Err(LineCheckError::ImproperlyFormatted);
|
|
||||||
}
|
|
||||||
let mut algo = detect_algo(&algo_name, length)?;
|
let mut algo = detect_algo(&algo_name, length)?;
|
||||||
|
|
||||||
let (filename_to_check_unescaped, prefix) = unescape_filename(filename_to_check);
|
let (filename_to_check_unescaped, prefix) = unescape_filename(filename_to_check);
|
||||||
|
@ -689,7 +671,6 @@ fn process_checksum_line(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
res.bad_format += 1;
|
|
||||||
Err(LineCheckError::ImproperlyFormatted)
|
Err(LineCheckError::ImproperlyFormatted)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -701,8 +682,9 @@ fn process_checksum_file(
|
||||||
opts: ChecksumOptions,
|
opts: ChecksumOptions,
|
||||||
) -> Result<(), FileCheckError> {
|
) -> Result<(), FileCheckError> {
|
||||||
let mut correct_format = 0;
|
let mut correct_format = 0;
|
||||||
let mut properly_formatted = false;
|
let mut properly_formatted_lines = 0;
|
||||||
let mut res = ChecksumResult::default();
|
let mut res = ChecksumResult::default();
|
||||||
|
|
||||||
let input_is_stdin = filename_input == OsStr::new("-");
|
let input_is_stdin = filename_input == OsStr::new("-");
|
||||||
|
|
||||||
let file: Box<dyn Read> = if input_is_stdin {
|
let file: Box<dyn Read> = if input_is_stdin {
|
||||||
|
@ -724,10 +706,7 @@ fn process_checksum_file(
|
||||||
let lines = read_os_string_lines(reader).collect::<Vec<_>>();
|
let lines = read_os_string_lines(reader).collect::<Vec<_>>();
|
||||||
|
|
||||||
let Some((chosen_regex, is_algo_based_format)) = determine_regex(&lines) else {
|
let Some((chosen_regex, is_algo_based_format)) = determine_regex(&lines) else {
|
||||||
let e = ChecksumError::NoProperlyFormattedChecksumLinesFound {
|
log_no_properly_formatted(get_filename_for_output(filename_input, input_is_stdin));
|
||||||
filename: get_filename_for_output(filename_input, input_is_stdin),
|
|
||||||
};
|
|
||||||
show_error!("{e}");
|
|
||||||
set_exit_code(1);
|
set_exit_code(1);
|
||||||
return Err(FileCheckError::AlgoDetectionError);
|
return Err(FileCheckError::AlgoDetectionError);
|
||||||
};
|
};
|
||||||
|
@ -739,21 +718,27 @@ fn process_checksum_file(
|
||||||
i,
|
i,
|
||||||
&chosen_regex,
|
&chosen_regex,
|
||||||
is_algo_based_format,
|
is_algo_based_format,
|
||||||
&mut res,
|
|
||||||
cli_algo_name,
|
cli_algo_name,
|
||||||
cli_algo_length,
|
cli_algo_length,
|
||||||
&mut properly_formatted,
|
|
||||||
opts,
|
opts,
|
||||||
) {
|
) {
|
||||||
Ok(()) => correct_format += 1,
|
Ok(()) => {
|
||||||
Err(LineCheckError::DigestMismatch) => res.failed_cksum += 1,
|
correct_format += 1;
|
||||||
|
properly_formatted_lines += 1
|
||||||
|
}
|
||||||
|
Err(LineCheckError::DigestMismatch) => {
|
||||||
|
res.failed_cksum += 1;
|
||||||
|
properly_formatted_lines += 1
|
||||||
|
}
|
||||||
Err(LineCheckError::UError(e)) => return Err(e.into()),
|
Err(LineCheckError::UError(e)) => return Err(e.into()),
|
||||||
Err(LineCheckError::Skipped) => continue,
|
Err(LineCheckError::Skipped) => continue,
|
||||||
Err(LineCheckError::ImproperlyFormatted) => (),
|
Err(LineCheckError::ImproperlyFormatted) => res.bad_format += 1,
|
||||||
Err(LineCheckError::CantOpenFile | LineCheckError::FileIsDirectory) => {
|
Err(LineCheckError::CantOpenFile | LineCheckError::FileIsDirectory) => {
|
||||||
|
properly_formatted_lines += 1;
|
||||||
res.failed_open_file += 1
|
res.failed_open_file += 1
|
||||||
}
|
}
|
||||||
Err(LineCheckError::FileNotFound) => {
|
Err(LineCheckError::FileNotFound) => {
|
||||||
|
properly_formatted_lines += 1;
|
||||||
if !opts.ignore_missing {
|
if !opts.ignore_missing {
|
||||||
res.failed_open_file += 1
|
res.failed_open_file += 1
|
||||||
}
|
}
|
||||||
|
@ -763,12 +748,9 @@ fn process_checksum_file(
|
||||||
|
|
||||||
// not a single line correctly formatted found
|
// not a single line correctly formatted found
|
||||||
// return an error
|
// return an error
|
||||||
if !properly_formatted {
|
if properly_formatted_lines == 0 {
|
||||||
if !opts.status {
|
if !opts.status {
|
||||||
return Err(ChecksumError::NoProperlyFormattedChecksumLinesFound {
|
log_no_properly_formatted(get_filename_for_output(filename_input, input_is_stdin));
|
||||||
filename: get_filename_for_output(filename_input, input_is_stdin),
|
|
||||||
}
|
|
||||||
.into());
|
|
||||||
}
|
}
|
||||||
set_exit_code(1);
|
set_exit_code(1);
|
||||||
return Err(FileCheckError::ImproperlyFormatted);
|
return Err(FileCheckError::ImproperlyFormatted);
|
||||||
|
@ -1234,7 +1216,7 @@ mod tests {
|
||||||
.captures(b"SHA256 (empty) = 47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=")
|
.captures(b"SHA256 (empty) = 47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=")
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let result = get_expected_digest_as_hexa_string(&caps, &re);
|
let result = get_expected_digest_as_hex_string(&caps, &re);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
result.unwrap(),
|
result.unwrap(),
|
||||||
|
@ -1249,7 +1231,7 @@ mod tests {
|
||||||
.captures(b"SHA256 (empty) = 47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU")
|
.captures(b"SHA256 (empty) = 47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU")
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let result = get_expected_digest_as_hexa_string(&caps, &re);
|
let result = get_expected_digest_as_hex_string(&caps, &re);
|
||||||
|
|
||||||
assert!(result.is_none());
|
assert!(result.is_none());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue