Merge pull request #5581 from GDYendell/hashsum-remove-crash

hashsum: Remove usage of crash! macro
This commit is contained in:
Terts Diepraam 2023-11-26 12:25:50 +01:00 committed by GitHub
commit cd4f455a77
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -20,12 +20,13 @@ use std::io::{self, stdin, BufRead, BufReader, Read};
use std::iter; use std::iter;
use std::num::ParseIntError; use std::num::ParseIntError;
use std::path::Path; use std::path::Path;
use uucore::error::USimpleError;
use uucore::error::{FromIo, UError, UResult}; use uucore::error::{FromIo, UError, UResult};
use uucore::sum::{ use uucore::sum::{
Blake2b, Blake3, Digest, DigestWriter, Md5, Sha1, Sha224, Sha256, Sha384, Sha3_224, Sha3_256, Blake2b, Blake3, Digest, DigestWriter, Md5, Sha1, Sha224, Sha256, Sha384, Sha3_224, Sha3_256,
Sha3_384, Sha3_512, Sha512, Shake128, Shake256, Sha3_384, Sha3_512, Sha512, Shake128, Shake256,
}; };
use uucore::{crash, display::Quotable, show_warning}; use uucore::{display::Quotable, show_warning};
use uucore::{format_usage, help_about, help_usage}; use uucore::{format_usage, help_about, help_usage};
const NAME: &str = "hashsum"; const NAME: &str = "hashsum";
@ -51,28 +52,32 @@ struct Options {
/// ///
/// # Returns /// # Returns
/// ///
/// Returns a tuple containing the algorithm name, the hasher instance, and the output length in bits. /// Returns a UResult of a tuple containing the algorithm name, the hasher instance, and
/// /// the output length in bits or an Err if the length is not a multiple of 8 or if it is
/// # Panics /// greater than 512.
/// fn create_blake2b(matches: &ArgMatches) -> UResult<(&'static str, Box<dyn Digest>, usize)> {
/// Panics if the length is not a multiple of 8 or if it is greater than 512.
fn create_blake2b(matches: &ArgMatches) -> (&'static str, Box<dyn Digest>, usize) {
match matches.get_one::<usize>("length") { match matches.get_one::<usize>("length") {
Some(0) | None => ("BLAKE2", Box::new(Blake2b::new()) as Box<dyn Digest>, 512), Some(0) | None => Ok(("BLAKE2", Box::new(Blake2b::new()) as Box<dyn Digest>, 512)),
Some(length_in_bits) => { Some(length_in_bits) => {
if *length_in_bits > 512 { if *length_in_bits > 512 {
crash!(1, "Invalid length (maximum digest length is 512 bits)") return Err(USimpleError::new(
1,
"Invalid length (maximum digest length is 512 bits)",
));
} }
if length_in_bits % 8 == 0 { if length_in_bits % 8 == 0 {
let length_in_bytes = length_in_bits / 8; let length_in_bytes = length_in_bits / 8;
( Ok((
"BLAKE2", "BLAKE2",
Box::new(Blake2b::with_output_bytes(length_in_bytes)), Box::new(Blake2b::with_output_bytes(length_in_bytes)),
*length_in_bits, *length_in_bits,
) ))
} else { } else {
crash!(1, "Invalid length (expected a multiple of 8)") Err(USimpleError::new(
1,
"Invalid length (expected a multiple of 8)",
))
} }
} }
} }
@ -82,38 +87,36 @@ fn create_blake2b(matches: &ArgMatches) -> (&'static str, Box<dyn Digest>, usize
/// ///
/// # Returns /// # Returns
/// ///
/// Returns a tuple containing the algorithm name, the hasher instance, and the output length in bits. /// Returns a UResult of a tuple containing the algorithm name, the hasher instance, and
/// /// the output length in bits or an Err if an unsupported output size is provided, or if
/// # Panics /// the `--bits` flag is missing.
/// fn create_sha3(matches: &ArgMatches) -> UResult<(&'static str, Box<dyn Digest>, usize)> {
/// Panics if an unsupported output size is provided, or if the `--bits` flag is missing.
fn create_sha3(matches: &ArgMatches) -> (&'static str, Box<dyn Digest>, usize) {
match matches.get_one::<usize>("bits") { match matches.get_one::<usize>("bits") {
Some(224) => ( Some(224) => Ok((
"SHA3-224", "SHA3-224",
Box::new(Sha3_224::new()) as Box<dyn Digest>, Box::new(Sha3_224::new()) as Box<dyn Digest>,
224, 224,
), )),
Some(256) => ( Some(256) => Ok((
"SHA3-256", "SHA3-256",
Box::new(Sha3_256::new()) as Box<dyn Digest>, Box::new(Sha3_256::new()) as Box<dyn Digest>,
256, 256,
), )),
Some(384) => ( Some(384) => Ok((
"SHA3-384", "SHA3-384",
Box::new(Sha3_384::new()) as Box<dyn Digest>, Box::new(Sha3_384::new()) as Box<dyn Digest>,
384, 384,
), )),
Some(512) => ( Some(512) => Ok((
"SHA3-512", "SHA3-512",
Box::new(Sha3_512::new()) as Box<dyn Digest>, Box::new(Sha3_512::new()) as Box<dyn Digest>,
512, 512,
), )),
Some(_) => crash!( Some(_) => Err(USimpleError::new(
1, 1,
"Invalid output size for SHA3 (expected 224, 256, 384, or 512)" "Invalid output size for SHA3 (expected 224, 256, 384, or 512)",
), )),
None => crash!(1, "--bits required for SHA3"), None => Err(USimpleError::new(1, "--bits required for SHA3")),
} }
} }
@ -121,19 +124,16 @@ fn create_sha3(matches: &ArgMatches) -> (&'static str, Box<dyn Digest>, usize) {
/// ///
/// # Returns /// # Returns
/// ///
/// Returns a tuple containing the algorithm name, the hasher instance, and the output length in bits. /// Returns a UResult of a tuple containing the algorithm name, the hasher instance, and
/// /// the output length in bits, or an Err if `--bits` flag is missing.
/// # Panics fn create_shake128(matches: &ArgMatches) -> UResult<(&'static str, Box<dyn Digest>, usize)> {
///
/// Panics if the `--bits` flag is missing.
fn create_shake128(matches: &ArgMatches) -> (&'static str, Box<dyn Digest>, usize) {
match matches.get_one::<usize>("bits") { match matches.get_one::<usize>("bits") {
Some(bits) => ( Some(bits) => Ok((
"SHAKE128", "SHAKE128",
Box::new(Shake128::new()) as Box<dyn Digest>, Box::new(Shake128::new()) as Box<dyn Digest>,
*bits, *bits,
), )),
None => crash!(1, "--bits required for SHAKE-128"), None => Err(USimpleError::new(1, "--bits required for SHAKE-128")),
} }
} }
@ -141,19 +141,16 @@ fn create_shake128(matches: &ArgMatches) -> (&'static str, Box<dyn Digest>, usiz
/// ///
/// # Returns /// # Returns
/// ///
/// Returns a tuple containing the algorithm name, the hasher instance, and the output length in bits. /// Returns a UResult of a tuple containing the algorithm name, the hasher instance, and
/// /// the output length in bits, or an Err if the `--bits` flag is missing.
/// # Panics fn create_shake256(matches: &ArgMatches) -> UResult<(&'static str, Box<dyn Digest>, usize)> {
///
/// Panics if the `--bits` flag is missing.
fn create_shake256(matches: &ArgMatches) -> (&'static str, Box<dyn Digest>, usize) {
match matches.get_one::<usize>("bits") { match matches.get_one::<usize>("bits") {
Some(bits) => ( Some(bits) => Ok((
"SHAKE256", "SHAKE256",
Box::new(Shake256::new()) as Box<dyn Digest>, Box::new(Shake256::new()) as Box<dyn Digest>,
*bits, *bits,
), )),
None => crash!(1, "--bits required for SHAKE-256"), None => Err(USimpleError::new(1, "--bits required for SHAKE-256")),
} }
} }
@ -166,46 +163,46 @@ fn create_shake256(matches: &ArgMatches) -> (&'static str, Box<dyn Digest>, usiz
/// ///
/// # Returns /// # Returns
/// ///
/// Returns a tuple containing the algorithm name, the hasher instance, and the output length in bits. /// Returns a UResult of a tuple containing the algorithm name, the hasher instance, and
/// the output length in bits, or an Err if a matching algorithm is not found.
fn detect_algo( fn detect_algo(
program: &str, program: &str,
matches: &ArgMatches, matches: &ArgMatches,
) -> (&'static str, Box<dyn Digest + 'static>, usize) { ) -> UResult<(&'static str, Box<dyn Digest + 'static>, usize)> {
let (name, alg, output_bits) = match program { match program {
"md5sum" => ("MD5", Box::new(Md5::new()) as Box<dyn Digest>, 128), "md5sum" => Ok(("MD5", Box::new(Md5::new()) as Box<dyn Digest>, 128)),
"sha1sum" => ("SHA1", Box::new(Sha1::new()) as Box<dyn Digest>, 160), "sha1sum" => Ok(("SHA1", Box::new(Sha1::new()) as Box<dyn Digest>, 160)),
"sha224sum" => ("SHA224", Box::new(Sha224::new()) as Box<dyn Digest>, 224), "sha224sum" => Ok(("SHA224", Box::new(Sha224::new()) as Box<dyn Digest>, 224)),
"sha256sum" => ("SHA256", Box::new(Sha256::new()) as Box<dyn Digest>, 256), "sha256sum" => Ok(("SHA256", Box::new(Sha256::new()) as Box<dyn Digest>, 256)),
"sha384sum" => ("SHA384", Box::new(Sha384::new()) as Box<dyn Digest>, 384), "sha384sum" => Ok(("SHA384", Box::new(Sha384::new()) as Box<dyn Digest>, 384)),
"sha512sum" => ("SHA512", Box::new(Sha512::new()) as Box<dyn Digest>, 512), "sha512sum" => Ok(("SHA512", Box::new(Sha512::new()) as Box<dyn Digest>, 512)),
"b2sum" => create_blake2b(matches), "b2sum" => create_blake2b(matches),
"b3sum" => ("BLAKE3", Box::new(Blake3::new()) as Box<dyn Digest>, 256), "b3sum" => Ok(("BLAKE3", Box::new(Blake3::new()) as Box<dyn Digest>, 256)),
"sha3sum" => create_sha3(matches), "sha3sum" => create_sha3(matches),
"sha3-224sum" => ( "sha3-224sum" => Ok((
"SHA3-224", "SHA3-224",
Box::new(Sha3_224::new()) as Box<dyn Digest>, Box::new(Sha3_224::new()) as Box<dyn Digest>,
224, 224,
), )),
"sha3-256sum" => ( "sha3-256sum" => Ok((
"SHA3-256", "SHA3-256",
Box::new(Sha3_256::new()) as Box<dyn Digest>, Box::new(Sha3_256::new()) as Box<dyn Digest>,
256, 256,
), )),
"sha3-384sum" => ( "sha3-384sum" => Ok((
"SHA3-384", "SHA3-384",
Box::new(Sha3_384::new()) as Box<dyn Digest>, Box::new(Sha3_384::new()) as Box<dyn Digest>,
384, 384,
), )),
"sha3-512sum" => ( "sha3-512sum" => Ok((
"SHA3-512", "SHA3-512",
Box::new(Sha3_512::new()) as Box<dyn Digest>, Box::new(Sha3_512::new()) as Box<dyn Digest>,
512, 512,
), )),
"shake128sum" => create_shake128(matches), "shake128sum" => create_shake128(matches),
"shake256sum" => create_shake256(matches), "shake256sum" => create_shake256(matches),
_ => create_algorithm_from_flags(matches), _ => create_algorithm_from_flags(matches),
}; }
(name, alg, output_bits)
} }
/// Creates a hasher instance based on the command-line flags. /// Creates a hasher instance based on the command-line flags.
@ -216,80 +213,89 @@ fn detect_algo(
/// ///
/// # Returns /// # Returns
/// ///
/// Returns a tuple containing the algorithm name, the hasher instance, and the output length in bits. /// Returns a UResult of a tuple containing the algorithm name, the hasher instance, and
/// /// the output length in bits or an Err if multiple hash algorithms are specified or if a
/// # Panics /// required flag is missing.
///
/// Panics if multiple hash algorithms are specified or if a required flag is missing.
#[allow(clippy::cognitive_complexity)] #[allow(clippy::cognitive_complexity)]
fn create_algorithm_from_flags(matches: &ArgMatches) -> (&'static str, Box<dyn Digest>, usize) { fn create_algorithm_from_flags(
matches: &ArgMatches,
) -> UResult<(&'static str, Box<dyn Digest>, usize)> {
let mut alg: Option<Box<dyn Digest>> = None; let mut alg: Option<Box<dyn Digest>> = None;
let mut name: &'static str = ""; let mut name: &'static str = "";
let mut output_bits = 0; let mut output_bits = 0;
let mut set_or_crash = |n, val, bits| { let mut set_or_err = |n, val, bits| {
if alg.is_some() { if alg.is_some() {
crash!(1, "You cannot combine multiple hash algorithms!"); return Err(USimpleError::new(
1,
"You cannot combine multiple hash algorithms!",
));
}; };
name = n; name = n;
alg = Some(val); alg = Some(val);
output_bits = bits; output_bits = bits;
Ok(())
}; };
if matches.get_flag("md5") { if matches.get_flag("md5") {
set_or_crash("MD5", Box::new(Md5::new()), 128); set_or_err("MD5", Box::new(Md5::new()), 128)?;
} }
if matches.get_flag("sha1") { if matches.get_flag("sha1") {
set_or_crash("SHA1", Box::new(Sha1::new()), 160); set_or_err("SHA1", Box::new(Sha1::new()), 160)?;
} }
if matches.get_flag("sha224") { if matches.get_flag("sha224") {
set_or_crash("SHA224", Box::new(Sha224::new()), 224); set_or_err("SHA224", Box::new(Sha224::new()), 224)?;
} }
if matches.get_flag("sha256") { if matches.get_flag("sha256") {
set_or_crash("SHA256", Box::new(Sha256::new()), 256); set_or_err("SHA256", Box::new(Sha256::new()), 256)?;
} }
if matches.get_flag("sha384") { if matches.get_flag("sha384") {
set_or_crash("SHA384", Box::new(Sha384::new()), 384); set_or_err("SHA384", Box::new(Sha384::new()), 384)?;
} }
if matches.get_flag("sha512") { if matches.get_flag("sha512") {
set_or_crash("SHA512", Box::new(Sha512::new()), 512); set_or_err("SHA512", Box::new(Sha512::new()), 512)?;
} }
if matches.get_flag("b2sum") { if matches.get_flag("b2sum") {
set_or_crash("BLAKE2", Box::new(Blake2b::new()), 512); set_or_err("BLAKE2", Box::new(Blake2b::new()), 512)?;
} }
if matches.get_flag("b3sum") { if matches.get_flag("b3sum") {
set_or_crash("BLAKE3", Box::new(Blake3::new()), 256); set_or_err("BLAKE3", Box::new(Blake3::new()), 256)?;
} }
if matches.get_flag("sha3") { if matches.get_flag("sha3") {
let (n, val, bits) = create_sha3(matches); let (n, val, bits) = create_sha3(matches)?;
set_or_crash(n, val, bits); set_or_err(n, val, bits)?;
} }
if matches.get_flag("sha3-224") { if matches.get_flag("sha3-224") {
set_or_crash("SHA3-224", Box::new(Sha3_224::new()), 224); set_or_err("SHA3-224", Box::new(Sha3_224::new()), 224)?;
} }
if matches.get_flag("sha3-256") { if matches.get_flag("sha3-256") {
set_or_crash("SHA3-256", Box::new(Sha3_256::new()), 256); set_or_err("SHA3-256", Box::new(Sha3_256::new()), 256)?;
} }
if matches.get_flag("sha3-384") { if matches.get_flag("sha3-384") {
set_or_crash("SHA3-384", Box::new(Sha3_384::new()), 384); set_or_err("SHA3-384", Box::new(Sha3_384::new()), 384)?;
} }
if matches.get_flag("sha3-512") { if matches.get_flag("sha3-512") {
set_or_crash("SHA3-512", Box::new(Sha3_512::new()), 512); set_or_err("SHA3-512", Box::new(Sha3_512::new()), 512)?;
} }
if matches.get_flag("shake128") { if matches.get_flag("shake128") {
match matches.get_one::<usize>("bits") { match matches.get_one::<usize>("bits") {
Some(bits) => set_or_crash("SHAKE128", Box::new(Shake128::new()), *bits), Some(bits) => set_or_err("SHAKE128", Box::new(Shake128::new()), *bits)?,
None => crash!(1, "--bits required for SHAKE-128"), None => return Err(USimpleError::new(1, "--bits required for SHAKE-128")),
} };
} }
if matches.get_flag("shake256") { if matches.get_flag("shake256") {
match matches.get_one::<usize>("bits") { match matches.get_one::<usize>("bits") {
Some(bits) => set_or_crash("SHAKE256", Box::new(Shake256::new()), *bits), Some(bits) => set_or_err("SHAKE256", Box::new(Shake256::new()), *bits)?,
None => crash!(1, "--bits required for SHAKE-256"), None => return Err(USimpleError::new(1, "--bits required for SHAKE-256")),
} };
} }
let alg = alg.unwrap_or_else(|| crash!(1, "You must specify hash algorithm!")); let alg = match alg {
(name, alg, output_bits) Some(a) => a,
None => return Err(USimpleError::new(1, "You must specify hash algorithm!")),
};
Ok((name, alg, output_bits))
} }
// TODO: return custom error type // TODO: return custom error type
@ -319,7 +325,7 @@ pub fn uumain(mut args: impl uucore::Args) -> UResult<()> {
// least somewhat better from a user's perspective. // least somewhat better from a user's perspective.
let matches = command.try_get_matches_from(args)?; let matches = command.try_get_matches_from(args)?;
let (name, algo, bits) = detect_algo(&binary_name, &matches); let (name, algo, bits) = detect_algo(&binary_name, &matches)?;
let binary = if matches.get_flag("binary") { let binary = if matches.get_flag("binary") {
true true