diff --git a/src/uu/cksum/src/cksum.rs b/src/uu/cksum/src/cksum.rs index c681b8f7a..fe3edbc44 100644 --- a/src/uu/cksum/src/cksum.rs +++ b/src/uu/cksum/src/cksum.rs @@ -5,21 +5,19 @@ // spell-checker:ignore (ToDO) fname, algo use clap::{crate_version, value_parser, Arg, ArgAction, Command}; -use std::error::Error; use std::ffi::OsStr; -use std::fmt::Display; use std::fs::File; use std::io::{self, stdin, stdout, BufReader, Read, Write}; use std::iter; use std::path::Path; use uucore::checksum::{ calculate_blake2b_length, detect_algo, digest_reader, perform_checksum_validation, - ALGORITHM_OPTIONS_BLAKE2B, ALGORITHM_OPTIONS_BSD, ALGORITHM_OPTIONS_CRC, + ChecksumError, ALGORITHM_OPTIONS_BLAKE2B, ALGORITHM_OPTIONS_BSD, ALGORITHM_OPTIONS_CRC, ALGORITHM_OPTIONS_SYSV, SUPPORTED_ALGO, }; use uucore::{ encoding, - error::{FromIo, UError, UResult, USimpleError}, + error::{FromIo, UResult, USimpleError}, format_usage, help_about, help_section, help_usage, show, sum::{div_ceil, Digest}, }; @@ -28,11 +26,6 @@ const USAGE: &str = help_usage!("cksum.md"); const ABOUT: &str = help_about!("cksum.md"); const AFTER_HELP: &str = help_section!("after help", "cksum.md"); -#[derive(Debug)] -enum CkSumError { - RawMultipleFiles, -} - #[derive(Debug, PartialEq)] enum OutputFormat { Hexadecimal, @@ -40,26 +33,6 @@ enum OutputFormat { Base64, } -impl UError for CkSumError { - fn code(&self) -> i32 { - match self { - Self::RawMultipleFiles => 1, - } - } -} - -impl Error for CkSumError {} - -impl Display for CkSumError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - Self::RawMultipleFiles => { - write!(f, "the --raw option is not supported with multiple files") - } - } - } -} - struct Options { algo_name: &'static str, digest: Box, @@ -83,7 +56,7 @@ where { let files: Vec<_> = files.collect(); if options.output_format == OutputFormat::Raw && files.len() > 1 { - return Err(Box::new(CkSumError::RawMultipleFiles)); + return Err(Box::new(ChecksumError::RawMultipleFiles)); } for filename in files { @@ -287,11 +260,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { }; if ["bsd", "crc", "sysv"].contains(&algo_name) && check { - return Err(io::Error::new( - io::ErrorKind::InvalidInput, - "--check is not supported with --algorithm={bsd,sysv,crc}", - ) - .into()); + return Err(ChecksumError::AlgorithmNotSupportedWithCheck.into()); } let input_length = matches.get_one::(options::LENGTH); @@ -301,11 +270,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { 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()); + return Err(ChecksumError::LengthOnlyForBlake2b.into()); } } None => None, @@ -320,11 +285,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { let ignore_missing = matches.get_flag(options::IGNORE_MISSING); if (binary_flag || text_flag) && check { - return Err(io::Error::new( - io::ErrorKind::InvalidInput, - "the --binary and --text options are meaningless when verifying checksums", - ) - .into()); + return Err(ChecksumError::BinaryTextConflict.into()); } // Determine the appropriate algorithm option to pass let algo_option = if algo_name.is_empty() { diff --git a/src/uu/hashsum/src/hashsum.rs b/src/uu/hashsum/src/hashsum.rs index 5dae16494..59a9a3352 100644 --- a/src/uu/hashsum/src/hashsum.rs +++ b/src/uu/hashsum/src/hashsum.rs @@ -10,10 +10,9 @@ use clap::crate_version; use clap::value_parser; use clap::ArgAction; use clap::{Arg, ArgMatches, Command}; -use std::error::Error; use std::ffi::{OsStr, OsString}; use std::fs::File; -use std::io::{self, stdin, BufReader, Read}; +use std::io::{stdin, BufReader, Read}; use std::iter; use std::num::ParseIntError; use std::path::Path; @@ -23,10 +22,10 @@ use uucore::checksum::detect_algo; use uucore::checksum::digest_reader; use uucore::checksum::escape_filename; use uucore::checksum::perform_checksum_validation; +use uucore::checksum::ChecksumError; use uucore::checksum::HashAlgorithm; use uucore::checksum::ALGORITHM_OPTIONS_BLAKE2B; -use uucore::error::USimpleError; -use uucore::error::{FromIo, UError, UResult}; +use uucore::error::{FromIo, UResult}; use uucore::sum::{Digest, Sha3_224, Sha3_256, Sha3_384, Sha3_512, Shake128, Shake256}; use uucore::{format_usage, help_about, help_usage}; @@ -67,10 +66,7 @@ fn create_algorithm_from_flags(matches: &ArgMatches) -> UResult { let mut set_or_err = |new_alg: HashAlgorithm| -> UResult<()> { if alg.is_some() { - return Err(USimpleError::new( - 1, - "You cannot combine multiple hash algorithms!", - )); + return Err(ChecksumError::CombineMultipleAlgorithms.into()); } alg = Some(new_alg); Ok(()) @@ -139,7 +135,7 @@ fn create_algorithm_from_flags(matches: &ArgMatches) -> UResult { create_fn: Box::new(|| Box::new(Shake128::new())), bits: *bits, })?, - None => return Err(USimpleError::new(1, "--bits required for SHAKE128")), + None => return Err(ChecksumError::BitsRequiredForShake128.into()), }; } if matches.get_flag("shake256") { @@ -149,15 +145,12 @@ fn create_algorithm_from_flags(matches: &ArgMatches) -> UResult { create_fn: Box::new(|| Box::new(Shake256::new())), bits: *bits, })?, - None => return Err(USimpleError::new(1, "--bits required for SHAKE256")), + None => return Err(ChecksumError::BitsRequiredForShake256.into()), }; } if alg.is_none() { - return Err(USimpleError::new( - 1, - "Needs an algorithm to hash with.\nUse --help for more information.", - )); + return Err(ChecksumError::NeedAlgoToHash.into()); } Ok(alg.unwrap()) @@ -201,11 +194,7 @@ pub fn uumain(mut args: impl uucore::Args) -> UResult<()> { if binary_name == ALGORITHM_OPTIONS_BLAKE2B || binary_name == "b2sum" { calculate_blake2b_length(*length)? } else { - return Err(io::Error::new( - io::ErrorKind::InvalidInput, - "--length is only supported with --algorithm=blake2b", - ) - .into()); + return Err(ChecksumError::LengthOnlyForBlake2b.into()); } } None => None, @@ -239,7 +228,7 @@ pub fn uumain(mut args: impl uucore::Args) -> UResult<()> { if ignore_missing && !check { // --ignore-missing needs -c - return Err(HashsumError::IgnoreNotCheck.into()); + return Err(ChecksumError::IgnoreNotCheck.into()); } let opts = Options { @@ -264,11 +253,7 @@ pub fn uumain(mut args: impl uucore::Args) -> UResult<()> { let strict = matches.get_flag("strict"); if (binary_flag || text_flag) && check { - return Err(io::Error::new( - io::ErrorKind::InvalidInput, - "the --binary and --text options are meaningless when verifying checksums", - ) - .into()); + return Err(ChecksumError::BinaryTextConflict.into()); } // Determine the appropriate algorithm option to pass let algo_option = if algo.name.is_empty() { @@ -524,27 +509,6 @@ fn uu_app(binary_name: &str) -> (Command, bool) { } } -#[derive(Debug)] -enum HashsumError { - //InvalidRegex, - IgnoreNotCheck, -} - -impl Error for HashsumError {} -impl UError for HashsumError {} - -impl std::fmt::Display for HashsumError { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - match self { - //Self::InvalidRegex => write!(f, "invalid regular expression"), - Self::IgnoreNotCheck => write!( - f, - "the --ignore-missing option is meaningful only when verifying checksums" - ), - } - } -} - #[allow(clippy::cognitive_complexity)] fn hashsum<'a, I>(mut options: Options, files: I) -> UResult<()> where diff --git a/src/uucore/src/lib/features/checksum.rs b/src/uucore/src/lib/features/checksum.rs index 6f7cdf69d..c24f0419c 100644 --- a/src/uucore/src/lib/features/checksum.rs +++ b/src/uucore/src/lib/features/checksum.rs @@ -6,14 +6,16 @@ use os_display::Quotable; use regex::Regex; use std::{ + error::Error, ffi::OsStr, + fmt::Display, fs::File, io::{self, BufReader, Read}, path::Path, }; use crate::{ - error::{set_exit_code, FromIo, UResult, USimpleError}, + error::{set_exit_code, FromIo, UError, UResult, USimpleError}, show, show_error, show_warning_caps, sum::{ Blake2b, Blake3, Digest, DigestWriter, Md5, Sha1, Sha224, Sha256, Sha384, Sha3_224, @@ -65,6 +67,74 @@ pub struct HashAlgorithm { pub bits: usize, } +#[derive(Debug)] +pub enum ChecksumError { + RawMultipleFiles, + IgnoreNotCheck, + InvalidOutputSizeForSha3, + BitsRequiredForSha3, + BitsRequiredForShake128, + BitsRequiredForShake256, + UnknownAlgorithm, + InvalidLength, + LengthOnlyForBlake2b, + BinaryTextConflict, + AlgorithmNotSupportedWithCheck, + CombineMultipleAlgorithms, + NeedAlgoToHash, +} + +impl Error for ChecksumError {} + +impl UError for ChecksumError { + fn code(&self) -> i32 { + 1 + } +} + +impl Display for ChecksumError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::RawMultipleFiles => { + write!(f, "the --raw option is not supported with multiple files") + } + Self::IgnoreNotCheck => write!( + f, + "the --ignore-missing option is meaningful only when verifying checksums" + ), + Self::InvalidOutputSizeForSha3 => write!( + f, + "Invalid output size for SHA3 (expected 224, 256, 384, or 512)" + ), + Self::BitsRequiredForSha3 => write!(f, "--bits required for SHA3"), + Self::BitsRequiredForShake128 => write!(f, "--bits required for SHAKE128"), + Self::BitsRequiredForShake256 => write!(f, "--bits required for SHAKE256"), + Self::UnknownAlgorithm => { + write!(f, "unknown algorithm: clap should have prevented this case") + } + Self::InvalidLength => write!(f, "length is not a multiple of 8"), + Self::LengthOnlyForBlake2b => { + write!(f, "--length is only supported with --algorithm=blake2b") + } + Self::BinaryTextConflict => write!( + f, + "the --binary and --text options are meaningless when verifying checksums" + ), + Self::AlgorithmNotSupportedWithCheck => write!( + f, + "--check is not supported with --algorithm={{bsd,sysv,crc}}" + ), + Self::CombineMultipleAlgorithms => { + write!(f, "You cannot combine multiple hash algorithms!") + } + Self::NeedAlgoToHash => write!( + f, + "Needs an algorithm to hash with.\nUse --help for more information." + ), + } + } +} + /// Creates a SHA3 hasher instance based on the specified bits argument. /// /// # Returns @@ -95,11 +165,8 @@ pub fn create_sha3(bits: Option) -> UResult { bits: 512, }), - Some(_) => Err(USimpleError::new( - 1, - "Invalid output size for SHA3 (expected 224, 256, 384, or 512)", - )), - None => Err(USimpleError::new(1, "--bits required for SHA3")), + Some(_) => Err(ChecksumError::InvalidOutputSizeForSha3.into()), + None => Err(ChecksumError::BitsRequiredForSha3.into()), } } @@ -228,10 +295,7 @@ pub fn detect_algo(algo: &str, length: Option) -> UResult //ALGORITHM_OPTIONS_SHA3 | "sha3" => ( alg if alg.starts_with("sha3") => create_sha3(length), - _ => Err(USimpleError::new( - 1, - "unknown algorithm: clap should have prevented this case", - )), + _ => Err(ChecksumError::UnknownAlgorithm.into()), } } diff --git a/tests/by-util/test_cksum.rs b/tests/by-util/test_cksum.rs index 3498f589f..c1bd492c9 100644 --- a/tests/by-util/test_cksum.rs +++ b/tests/by-util/test_cksum.rs @@ -561,8 +561,7 @@ fn test_blake2b_512() { .arg("--check") .arg("checksum") .succeeds() - .stdout_contains("") - .stderr_contains(""); + .no_output(); } #[test] diff --git a/tests/by-util/test_hashsum.rs b/tests/by-util/test_hashsum.rs index 424a9b56e..c6199fdc1 100644 --- a/tests/by-util/test_hashsum.rs +++ b/tests/by-util/test_hashsum.rs @@ -370,7 +370,7 @@ fn test_check_md5sum_not_enough_space() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; - for f in &["a", " b"] { + for f in ["a", "b"] { at.write(f, &format!("{f}\n")); } at.write( @@ -384,8 +384,7 @@ fn test_check_md5sum_not_enough_space() { .arg("-c") .arg("check.md5sum") .fails() - .stdout_is("") - .stderr_is("md5sum: check.md5sum: no properly formatted checksum lines found\nmd5sum: WARNING: 2 lines are improperly formatted\n"); + .stderr_only("md5sum: check.md5sum: no properly formatted checksum lines found\nmd5sum: WARNING: 2 lines are improperly formatted\n"); } #[test]