1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-28 11:37:44 +00:00

cksum: various improvements/fixes

This commit is contained in:
Sylvestre Ledru 2024-05-14 19:17:19 +02:00
parent 843275a136
commit bbd80e4061
2 changed files with 81 additions and 36 deletions

View file

@ -15,6 +15,7 @@ use std::io::{self, stdin, stdout, BufReader, Read, Write};
use std::iter; use std::iter;
use std::path::Path; use std::path::Path;
use uucore::checksum::cksum_output; use uucore::checksum::cksum_output;
use uucore::display::Quotable;
use uucore::error::set_exit_code; use uucore::error::set_exit_code;
use uucore::{ use uucore::{
encoding, encoding,
@ -419,8 +420,9 @@ where
{ {
// Regexp to handle the two input formats: // Regexp to handle the two input formats:
// 1. <algo>[-<bits>] (<filename>) = <checksum> // 1. <algo>[-<bits>] (<filename>) = <checksum>
// algo must be uppercase or b (for blake2b)
// 2. <checksum> [* ]<filename> // 2. <checksum> [* ]<filename>
let regex_pattern = r"^(?P<algo>\w+)(-(?P<bits>\d+))?\s?\((?P<filename1>.*)\) = (?P<checksum1>[a-fA-F0-9]+)$|^(?P<checksum2>[a-fA-F0-9]+)\s[* ](?P<filename2>.*)"; let regex_pattern = r"^(?P<algo>[A-Z0-9b]+)(-(?P<bits>\d+))?\s?\((?P<filename1>.*)\) = (?P<checksum1>[a-fA-F0-9]+)$|^(?P<checksum2>[a-fA-F0-9]+)\s[* ](?P<filename2>.*)";
let re = Regex::new(regex_pattern).unwrap(); let re = Regex::new(regex_pattern).unwrap();
// if cksum has several input files, it will print the result for each file // if cksum has several input files, it will print the result for each file
@ -474,7 +476,7 @@ where
.as_str(); .as_str();
// 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_details = if algo_based_format { let (algo_name, length) = if algo_based_format {
// 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.name("algo").map_or("", |m| m.as_str()).to_lowercase(); let algorithm = caps.name("algo").map_or("", |m| m.as_str()).to_lowercase();
let bits = caps let bits = caps
@ -488,18 +490,18 @@ where
// 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) (String::new(), None)
}; };
if algo_based_format
&& algo_name_input.map_or(false, |input| algo_details.0 != input) if algo_based_format && algo_name_input.map_or(false, |input| algo_name != input) {
{
bad_format += 1; bad_format += 1;
continue; continue;
} }
if algo_details.0.is_empty() {
if algo_name.is_empty() {
// we haven't been able to detect the algo name. No point to continue // we haven't been able to detect the algo name. No point to continue
properly_formatted = false; properly_formatted = false;
continue; continue;
} }
let (_, mut algo, bits) = detect_algo(&algo_details.0, algo_details.1); let (_, mut algo, bits) = detect_algo(&algo_name, length);
// manage the input file // manage the input file
let file_to_check: Box<dyn Read> = if filename_to_check == "-" { let file_to_check: Box<dyn Read> = if filename_to_check == "-" {
@ -538,9 +540,15 @@ where
// 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 {
let filename = filename_input.to_string_lossy();
uucore::show_error!( uucore::show_error!(
"{}: no properly formatted checksum lines found", "{}: no properly formatted checksum lines found",
filename_input.to_string_lossy() if input_is_stdin {
"standard input"
} else {
&filename
}
.maybe_quote()
); );
set_exit_code(1); set_exit_code(1);
} }
@ -586,6 +594,23 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
.into()); .into());
} }
let input_length = matches.get_one::<usize>(options::LENGTH);
let length = match input_length {
Some(length) => {
if algo_name == ALGORITHM_OPTIONS_BLAKE2B {
calculate_blake2b_length(*length)?
} else {
return Err(io::Error::new(
io::ErrorKind::InvalidInput,
"--length is only supported with --algorithm=blake2b",
)
.into());
}
}
None => None,
};
if check { if check {
let text_flag: bool = matches.get_flag(options::TEXT); let text_flag: bool = matches.get_flag(options::TEXT);
let binary_flag: bool = matches.get_flag(options::BINARY); let binary_flag: bool = matches.get_flag(options::BINARY);
@ -612,23 +637,6 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
}; };
} }
let input_length = matches.get_one::<usize>(options::LENGTH);
let length = match input_length {
Some(length) => {
if algo_name != ALGORITHM_OPTIONS_BLAKE2B {
return Err(io::Error::new(
io::ErrorKind::InvalidInput,
"--length is only supported with --algorithm=blake2b",
)
.into());
} else {
calculate_blake2b_length(*length)?
}
}
None => None,
};
let (tag, asterisk) = handle_tag_text_binary_flags(&matches)?; let (tag, asterisk) = handle_tag_text_binary_flags(&matches)?;
let (name, algo, bits) = detect_algo(algo_name, length); let (name, algo, bits) = detect_algo(algo_name, length);

View file

@ -316,6 +316,16 @@ fn test_length_with_wrong_algorithm() {
.no_stdout() .no_stdout()
.stderr_contains("cksum: --length is only supported with --algorithm=blake2b") .stderr_contains("cksum: --length is only supported with --algorithm=blake2b")
.code_is(1); .code_is(1);
new_ucmd!()
.arg("--length=16")
.arg("--algorithm=md5")
.arg("-c")
.arg("foo.sums")
.fails()
.no_stdout()
.stderr_contains("cksum: --length is only supported with --algorithm=blake2b")
.code_is(1);
} }
#[test] #[test]
@ -725,22 +735,36 @@ fn test_check_algo_err() {
.code_is(1); .code_is(1);
} }
#[test]
fn test_check_pipe() {
let scene = TestScenario::new(util_name!());
let at = &scene.fixtures;
at.touch("f");
scene
.ucmd()
.arg("--check")
.arg("-")
.pipe_in("f")
.fails()
.no_stdout()
.stderr_contains("cksum: 'standard input': no properly formatted checksum lines found")
.code_is(1);
}
#[test] #[test]
fn test_cksum_check() { fn test_cksum_check() {
let scene = TestScenario::new(util_name!()); let scene = TestScenario::new(util_name!());
let at = &scene.fixtures; let at = &scene.fixtures;
let commands = [
vec!["-a", "sha384"],
vec!["-a", "blake2b"],
vec!["-a", "blake2b", "-l", "384"],
vec!["-a", "sm3"],
];
at.touch("f"); at.touch("f");
at.touch("CHECKSUM"); at.write("CHECKSUM", "\
for command in &commands { SHA384 (f) = 38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b\n\
let result = scene.ucmd().args(command).arg("f").succeeds(); BLAKE2b (f) = 786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419d25e1031afee585313896444934eb04b903a685b1448b755d56f701afe9be2ce\n\
at.append("CHECKSUM", result.stdout_str()); BLAKE2b-384 (f) = b32811423377f52d7862286ee1a72ee540524380fda1724a6f25d7978c6fd3244a6caf0498812673c5e05ef583825100\n\
} SM3 (f) = 1ab21d8355cfa17f8e61194831e81a8f22bec8c728fefb747ed035eb5082aa2b\n");
scene scene
.ucmd() .ucmd()
.arg("--check") .arg("--check")
@ -775,6 +799,19 @@ fn test_cksum_check() {
.stderr_contains("line is improperly formatted"); .stderr_contains("line is improperly formatted");
} }
#[test]
fn test_cksum_check_case() {
let scene = TestScenario::new(util_name!());
let at = &scene.fixtures;
at.touch("f");
at.write(
"CHECKSUM",
"Sha1 (f) = da39a3ee5e6b4b0d3255bfef95601890afd80709\n",
);
scene.ucmd().arg("--check").arg("CHECKSUM").fails();
}
#[test] #[test]
fn test_cksum_check_invalid() { fn test_cksum_check_invalid() {
let scene = TestScenario::new(util_name!()); let scene = TestScenario::new(util_name!());