From 8c1fc8b28743090f06aff52b132dfeacf1f2339d Mon Sep 17 00:00:00 2001 From: D9nni Date: Sun, 7 Jan 2024 21:43:31 +0200 Subject: [PATCH 1/7] Added --raw argument, with error for multiple files --- src/uu/cksum/src/cksum.rs | 55 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 4 deletions(-) diff --git a/src/uu/cksum/src/cksum.rs b/src/uu/cksum/src/cksum.rs index e8d7da60e..df8fdb5ea 100644 --- a/src/uu/cksum/src/cksum.rs +++ b/src/uu/cksum/src/cksum.rs @@ -8,11 +8,13 @@ use clap::{crate_version, value_parser, Arg, ArgAction, Command}; use hex::encode; use std::ffi::OsStr; use std::fs::File; -use std::io::{self, stdin, BufReader, Read}; +use std::io::{self, stdin, stdout, BufReader, Read, Write}; use std::iter; use std::path::Path; +use std::error::Error; +use std::fmt::Display; use uucore::{ - error::{FromIo, UResult}, + error::{FromIo, UResult, UError}, format_usage, help_about, help_section, help_usage, sum::{ div_ceil, Blake2b, Digest, DigestWriter, Md5, Sha1, Sha224, Sha256, Sha384, Sha512, Sm3, @@ -36,6 +38,32 @@ const ALGORITHM_OPTIONS_SHA512: &str = "sha512"; const ALGORITHM_OPTIONS_BLAKE2B: &str = "blake2b"; const ALGORITHM_OPTIONS_SM3: &str = "sm3"; +#[derive(Debug)] +enum CkSumError { + RawMultipleFiles, +} + +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") + } + } + } +} + fn detect_algo( program: &str, length: Option, @@ -110,6 +138,7 @@ struct Options { output_bits: usize, untagged: bool, length: Option, + raw: bool, } /// Calculate checksum @@ -123,7 +152,12 @@ fn cksum<'a, I>(mut options: Options, files: I) -> UResult<()> where I: Iterator, { - for filename in files { + let files_vec:Vec<_> = files.collect(); + if options.raw && files_vec.len() > 1 { + return Err(Box::new(CkSumError::RawMultipleFiles)); + } + + for filename in files_vec { let filename = Path::new(filename); let stdin_buf; let file_buf; @@ -140,7 +174,12 @@ where }); let (sum, sz) = digest_read(&mut options.digest, &mut file, options.output_bits) .map_err_context(|| "failed to read input".to_string())?; - + + if options.raw { + let bytes_str = sum.parse::().unwrap().to_be_bytes(); + stdout().write_all(&bytes_str)?; + return Ok(()); + } // The BSD checksum output is 5 digit integer let bsd_width = 5; match (options.algo_name, not_file) { @@ -231,6 +270,7 @@ mod options { pub const FILE: &str = "file"; pub const UNTAGGED: &str = "untagged"; pub const LENGTH: &str = "length"; + pub const RAW: &str = "raw"; } #[uucore::main] @@ -291,6 +331,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { output_bits: bits, length, untagged: matches.get_flag(options::UNTAGGED), + raw: matches.get_flag(options::RAW), }; match matches.get_many::(options::FILE) { @@ -346,6 +387,12 @@ pub fn uu_app() -> Command { .short('l') .help("digest length in bits; must not exceed the max for the blake2 algorithm and must be a multiple of 8") .action(ArgAction::Set), + ) + .arg( + Arg::new(options::RAW) + .long(options::RAW) + .help("emit a raw binary digest, not hexadecimal") + .action(ArgAction::SetTrue), ) .after_help(AFTER_HELP) } From f03ef79bc86ee58f688e5d0d36a684993d5a769a Mon Sep 17 00:00:00 2001 From: D9nni Date: Mon, 8 Jan 2024 08:51:06 +0200 Subject: [PATCH 2/7] cksum: added tests for --raw and fixed fmt whitespace error --- src/uu/cksum/src/cksum.rs | 17 ++++++++--------- tests/by-util/test_cksum.rs | 22 ++++++++++++++++++++++ 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/uu/cksum/src/cksum.rs b/src/uu/cksum/src/cksum.rs index df8fdb5ea..e3fb78ec4 100644 --- a/src/uu/cksum/src/cksum.rs +++ b/src/uu/cksum/src/cksum.rs @@ -6,15 +6,15 @@ // spell-checker:ignore (ToDO) fname, algo use clap::{crate_version, value_parser, Arg, ArgAction, Command}; use hex::encode; +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 std::error::Error; -use std::fmt::Display; use uucore::{ - error::{FromIo, UResult, UError}, + error::{FromIo, UError, UResult}, format_usage, help_about, help_section, help_usage, sum::{ div_ceil, Blake2b, Digest, DigestWriter, Md5, Sha1, Sha224, Sha256, Sha384, Sha512, Sm3, @@ -51,8 +51,7 @@ impl UError for CkSumError { } } -impl Error for CkSumError { -} +impl Error for CkSumError {} impl Display for CkSumError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { @@ -152,7 +151,7 @@ fn cksum<'a, I>(mut options: Options, files: I) -> UResult<()> where I: Iterator, { - let files_vec:Vec<_> = files.collect(); + let files_vec: Vec<_> = files.collect(); if options.raw && files_vec.len() > 1 { return Err(Box::new(CkSumError::RawMultipleFiles)); } @@ -174,7 +173,7 @@ where }); let (sum, sz) = digest_read(&mut options.digest, &mut file, options.output_bits) .map_err_context(|| "failed to read input".to_string())?; - + if options.raw { let bytes_str = sum.parse::().unwrap().to_be_bytes(); stdout().write_all(&bytes_str)?; @@ -331,7 +330,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { output_bits: bits, length, untagged: matches.get_flag(options::UNTAGGED), - raw: matches.get_flag(options::RAW), + raw: matches.get_flag(options::RAW), }; match matches.get_many::(options::FILE) { @@ -387,7 +386,7 @@ pub fn uu_app() -> Command { .short('l') .help("digest length in bits; must not exceed the max for the blake2 algorithm and must be a multiple of 8") .action(ArgAction::Set), - ) + ) .arg( Arg::new(options::RAW) .long(options::RAW) diff --git a/tests/by-util/test_cksum.rs b/tests/by-util/test_cksum.rs index 00c768164..a4e877b1c 100644 --- a/tests/by-util/test_cksum.rs +++ b/tests/by-util/test_cksum.rs @@ -286,3 +286,25 @@ fn test_length_is_zero() { .no_stderr() .stdout_is_fixture("length_is_zero.expected"); } + +#[test] +fn test_raw_single_file() { + new_ucmd!() + .arg("--raw") + .arg("lorem_ipsum.txt") + .succeeds() + .no_stderr() + .stdout_is_fixture("raw_single_file.expected"); +} + +#[test] +fn test_raw_multiple_files() { + new_ucmd!() + .arg("--raw") + .arg("lorem_ipsum.txt") + .arg("alice_in_wonderland.txt") + .fails() + .no_stdout() + .stderr_contains("cksum: the --raw option is not supported with multiple files") + .code_is(1); +} From 28b5224725fe93f445c49a02d975ccdb4abf4812 Mon Sep 17 00:00:00 2001 From: D9nni Date: Mon, 8 Jan 2024 15:50:25 +0200 Subject: [PATCH 3/7] cksum: fixed test for --raw on single file --- tests/by-util/test_cksum.rs | 2 +- tests/fixtures/cksum/raw_single_file.expected | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 tests/fixtures/cksum/raw_single_file.expected diff --git a/tests/by-util/test_cksum.rs b/tests/by-util/test_cksum.rs index 2d4fad923..52ac09911 100644 --- a/tests/by-util/test_cksum.rs +++ b/tests/by-util/test_cksum.rs @@ -294,7 +294,7 @@ fn test_raw_single_file() { .arg("lorem_ipsum.txt") .succeeds() .no_stderr() - .stdout_is_fixture("raw_single_file.expected"); + .stdout_is_fixture_bytes("raw_single_file.expected"); } #[test] diff --git a/tests/fixtures/cksum/raw_single_file.expected b/tests/fixtures/cksum/raw_single_file.expected new file mode 100644 index 000000000..de175b045 --- /dev/null +++ b/tests/fixtures/cksum/raw_single_file.expected @@ -0,0 +1 @@ +Ph \ No newline at end of file From 96271ffa3cb9588c97dddddc186a28ef4bbcb43a Mon Sep 17 00:00:00 2001 From: D9nni Date: Tue, 9 Jan 2024 23:12:40 +0200 Subject: [PATCH 4/7] cksum: added tests for --raw with each algorithm, not working for crc, sysv, bsd --- src/uu/cksum/src/cksum.rs | 19 +++++++++++++----- tests/by-util/test_cksum.rs | 16 ++++++++------- .../cksum/raw/blake2b_single_file.expected | 1 + .../cksum/raw/bsd_single_file.expected | 1 + .../crc_single_file.expected} | 0 .../cksum/raw/md5_single_file.expected | Bin 0 -> 16 bytes .../cksum/raw/sha1_single_file.expected | 1 + .../cksum/raw/sha224_single_file.expected | Bin 0 -> 28 bytes .../cksum/raw/sha256_single_file.expected | 1 + .../cksum/raw/sha384_single_file.expected | 3 +++ .../cksum/raw/sha512_single_file.expected | 1 + .../cksum/raw/sm3_single_file.expected | 1 + .../cksum/raw/sysv_single_file.expected | 1 + 13 files changed, 33 insertions(+), 12 deletions(-) create mode 100644 tests/fixtures/cksum/raw/blake2b_single_file.expected create mode 100644 tests/fixtures/cksum/raw/bsd_single_file.expected rename tests/fixtures/cksum/{raw_single_file.expected => raw/crc_single_file.expected} (100%) create mode 100644 tests/fixtures/cksum/raw/md5_single_file.expected create mode 100644 tests/fixtures/cksum/raw/sha1_single_file.expected create mode 100644 tests/fixtures/cksum/raw/sha224_single_file.expected create mode 100644 tests/fixtures/cksum/raw/sha256_single_file.expected create mode 100644 tests/fixtures/cksum/raw/sha384_single_file.expected create mode 100644 tests/fixtures/cksum/raw/sha512_single_file.expected create mode 100644 tests/fixtures/cksum/raw/sm3_single_file.expected create mode 100644 tests/fixtures/cksum/raw/sysv_single_file.expected diff --git a/src/uu/cksum/src/cksum.rs b/src/uu/cksum/src/cksum.rs index 40c06a386..6f3de690d 100644 --- a/src/uu/cksum/src/cksum.rs +++ b/src/uu/cksum/src/cksum.rs @@ -5,6 +5,7 @@ // spell-checker:ignore (ToDO) fname, algo use clap::{crate_version, value_parser, Arg, ArgAction, Command}; +use hex::decode; use hex::encode; use std::error::Error; use std::ffi::OsStr; @@ -151,12 +152,12 @@ fn cksum<'a, I>(mut options: Options, files: I) -> UResult<()> where I: Iterator, { - let files_vec: Vec<_> = files.collect(); - if options.raw && files_vec.len() > 1 { + let files: Vec<_> = files.collect(); + if options.raw && files.len() > 1 { return Err(Box::new(CkSumError::RawMultipleFiles)); } - for filename in files_vec { + for filename in files { let filename = Path::new(filename); let stdin_buf; let file_buf; @@ -175,8 +176,16 @@ where .map_err_context(|| "failed to read input".to_string())?; if options.raw { - let bytes_str = sum.parse::().unwrap().to_be_bytes(); - stdout().write_all(&bytes_str)?; + match decode(sum.clone()) { + Ok(bytes) => { + stdout().write_all(&bytes)?; + } + Err(_) => { + //bsd, sysv and crc have output generated without encode() + let bytes = sum.parse::().unwrap().to_be_bytes(); + stdout().write_all(&bytes)?; + } + } return Ok(()); } // The BSD checksum output is 5 digit integer diff --git a/tests/by-util/test_cksum.rs b/tests/by-util/test_cksum.rs index 52ac09911..b3db0bf0a 100644 --- a/tests/by-util/test_cksum.rs +++ b/tests/by-util/test_cksum.rs @@ -289,14 +289,16 @@ fn test_length_is_zero() { #[test] fn test_raw_single_file() { - new_ucmd!() - .arg("--raw") - .arg("lorem_ipsum.txt") - .succeeds() - .no_stderr() - .stdout_is_fixture_bytes("raw_single_file.expected"); + for algo in ALGOS { + new_ucmd!() + .arg("--raw") + .arg("lorem_ipsum.txt") + .arg(format!("--algorithm={algo}")) + .succeeds() + .no_stderr() + .stdout_is_fixture_bytes(format!("raw/{algo}_single_file.expected")); + } } - #[test] fn test_raw_multiple_files() { new_ucmd!() diff --git a/tests/fixtures/cksum/raw/blake2b_single_file.expected b/tests/fixtures/cksum/raw/blake2b_single_file.expected new file mode 100644 index 000000000..4955b2f99 --- /dev/null +++ b/tests/fixtures/cksum/raw/blake2b_single_file.expected @@ -0,0 +1 @@ +�����`�x� �f��W���Et�B��l��W^J�0�aX´��8�����5�B��9m�� \ No newline at end of file diff --git a/tests/fixtures/cksum/raw/bsd_single_file.expected b/tests/fixtures/cksum/raw/bsd_single_file.expected new file mode 100644 index 000000000..538ab19f7 --- /dev/null +++ b/tests/fixtures/cksum/raw/bsd_single_file.expected @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/tests/fixtures/cksum/raw_single_file.expected b/tests/fixtures/cksum/raw/crc_single_file.expected similarity index 100% rename from tests/fixtures/cksum/raw_single_file.expected rename to tests/fixtures/cksum/raw/crc_single_file.expected diff --git a/tests/fixtures/cksum/raw/md5_single_file.expected b/tests/fixtures/cksum/raw/md5_single_file.expected new file mode 100644 index 0000000000000000000000000000000000000000..e7b47aebbcba99b6dbaa03e825f0be3b5bfdb012 GIT binary patch literal 16 YcmX?GKH08Ru5cmMzZ literal 0 HcmV?d00001 diff --git a/tests/fixtures/cksum/raw/sha1_single_file.expected b/tests/fixtures/cksum/raw/sha1_single_file.expected new file mode 100644 index 000000000..0f634be47 --- /dev/null +++ b/tests/fixtures/cksum/raw/sha1_single_file.expected @@ -0,0 +1 @@ +к؈:=m毽(%, \ No newline at end of file diff --git a/tests/fixtures/cksum/raw/sha224_single_file.expected b/tests/fixtures/cksum/raw/sha224_single_file.expected new file mode 100644 index 0000000000000000000000000000000000000000..bc3fa6bf18f53f72894471200626992087ef971d GIT binary patch literal 28 kcmcD0mcM7MK%TV2YD?*-If0iL>Nfs77JA{!quGBL0mH`*$p8QV literal 0 HcmV?d00001 diff --git a/tests/fixtures/cksum/raw/sha256_single_file.expected b/tests/fixtures/cksum/raw/sha256_single_file.expected new file mode 100644 index 000000000..b9ce06f39 --- /dev/null +++ b/tests/fixtures/cksum/raw/sha256_single_file.expected @@ -0,0 +1 @@ + PP 0P g^ SkEC[+? \ No newline at end of file diff --git a/tests/fixtures/cksum/raw/sha384_single_file.expected b/tests/fixtures/cksum/raw/sha384_single_file.expected new file mode 100644 index 000000000..4b337f859 --- /dev/null +++ b/tests/fixtures/cksum/raw/sha384_single_file.expected @@ -0,0 +1,3 @@ +K + 2iJMϸ/gLZ{WZ3S +H \ No newline at end of file diff --git a/tests/fixtures/cksum/raw/sha512_single_file.expected b/tests/fixtures/cksum/raw/sha512_single_file.expected new file mode 100644 index 000000000..79f78cf00 --- /dev/null +++ b/tests/fixtures/cksum/raw/sha512_single_file.expected @@ -0,0 +1 @@ +Td%VՎsؚ!Yyu)f|T,Bn^OऊVgD k!= \ No newline at end of file diff --git a/tests/fixtures/cksum/raw/sm3_single_file.expected b/tests/fixtures/cksum/raw/sm3_single_file.expected new file mode 100644 index 000000000..3506406dc --- /dev/null +++ b/tests/fixtures/cksum/raw/sm3_single_file.expected @@ -0,0 +1 @@ +m)k] (0CyMg@pi \ No newline at end of file diff --git a/tests/fixtures/cksum/raw/sysv_single_file.expected b/tests/fixtures/cksum/raw/sysv_single_file.expected new file mode 100644 index 000000000..b975da49c --- /dev/null +++ b/tests/fixtures/cksum/raw/sysv_single_file.expected @@ -0,0 +1 @@ +I \ No newline at end of file From c7b15ddce9d2af52267511ce06b84bb32b843d82 Mon Sep 17 00:00:00 2001 From: D9nni Date: Wed, 10 Jan 2024 15:04:19 +0200 Subject: [PATCH 5/7] cksum: fixed cksum --raw --algorithm --- src/uu/cksum/src/cksum.rs | 23 ++++++++++++++----- .../cksum/raw/blake2b_single_file.expected | 2 +- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/uu/cksum/src/cksum.rs b/src/uu/cksum/src/cksum.rs index 6f3de690d..eeda3c083 100644 --- a/src/uu/cksum/src/cksum.rs +++ b/src/uu/cksum/src/cksum.rs @@ -176,16 +176,27 @@ where .map_err_context(|| "failed to read input".to_string())?; if options.raw { - match decode(sum.clone()) { - Ok(bytes) => { - stdout().write_all(&bytes)?; - } - Err(_) => { - //bsd, sysv and crc have output generated without encode() + match options.algo_name { + ALGORITHM_OPTIONS_CRC + | ALGORITHM_OPTIONS_SYSV + | ALGORITHM_OPTIONS_BSD => { let bytes = sum.parse::().unwrap().to_be_bytes(); + let mut first_nonzero = 0; + for byte in bytes { + if byte != 0 { + break; + } + first_nonzero += 1; + } + stdout().write_all(&bytes[first_nonzero..])?; + } + _ =>{ + let bytes = decode(sum).unwrap(); stdout().write_all(&bytes)?; } + } + return Ok(()); } // The BSD checksum output is 5 digit integer diff --git a/tests/fixtures/cksum/raw/blake2b_single_file.expected b/tests/fixtures/cksum/raw/blake2b_single_file.expected index 4955b2f99..19b311220 100644 --- a/tests/fixtures/cksum/raw/blake2b_single_file.expected +++ b/tests/fixtures/cksum/raw/blake2b_single_file.expected @@ -1 +1 @@ -�����`�x� �f��W���Et�B��l��W^J�0�aX´��8�����5�B��9m�� \ No newline at end of file +`x fWEtBlW^J0aX´85B9m \ No newline at end of file From 911df1d76cdc1d61f01b282b169dad246089b9f1 Mon Sep 17 00:00:00 2001 From: D9nni Date: Wed, 10 Jan 2024 15:15:23 +0200 Subject: [PATCH 6/7] cksum: code improvements for cksum --raw --algorithm --- src/uu/cksum/src/cksum.rs | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/src/uu/cksum/src/cksum.rs b/src/uu/cksum/src/cksum.rs index eeda3c083..40694fac6 100644 --- a/src/uu/cksum/src/cksum.rs +++ b/src/uu/cksum/src/cksum.rs @@ -176,27 +176,21 @@ where .map_err_context(|| "failed to read input".to_string())?; if options.raw { - match options.algo_name { - ALGORITHM_OPTIONS_CRC - | ALGORITHM_OPTIONS_SYSV - | ALGORITHM_OPTIONS_BSD => { + let bytes = match options.algo_name { + ALGORITHM_OPTIONS_CRC => { let bytes = sum.parse::().unwrap().to_be_bytes(); - let mut first_nonzero = 0; - for byte in bytes { - if byte != 0 { - break; - } - first_nonzero += 1; - } - stdout().write_all(&bytes[first_nonzero..])?; + bytes.to_vec() } - _ =>{ + ALGORITHM_OPTIONS_SYSV | ALGORITHM_OPTIONS_BSD => { + let bytes = sum.parse::().unwrap().to_be_bytes(); + bytes.to_vec() + } + _ => { let bytes = decode(sum).unwrap(); - stdout().write_all(&bytes)?; + bytes } - - } - + }; + stdout().write_all(&bytes)?; return Ok(()); } // The BSD checksum output is 5 digit integer From 9a76997b0a9d6d8b92b7c1d476f00d5cc45a74cc Mon Sep 17 00:00:00 2001 From: D9nni Date: Wed, 10 Jan 2024 16:49:52 +0200 Subject: [PATCH 7/7] cksum: fixed clippy and fmt errors --- src/uu/cksum/src/cksum.rs | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/uu/cksum/src/cksum.rs b/src/uu/cksum/src/cksum.rs index 40694fac6..a3e6dfd9e 100644 --- a/src/uu/cksum/src/cksum.rs +++ b/src/uu/cksum/src/cksum.rs @@ -177,18 +177,11 @@ where if options.raw { let bytes = match options.algo_name { - ALGORITHM_OPTIONS_CRC => { - let bytes = sum.parse::().unwrap().to_be_bytes(); - bytes.to_vec() - } + ALGORITHM_OPTIONS_CRC => sum.parse::().unwrap().to_be_bytes().to_vec(), ALGORITHM_OPTIONS_SYSV | ALGORITHM_OPTIONS_BSD => { - let bytes = sum.parse::().unwrap().to_be_bytes(); - bytes.to_vec() - } - _ => { - let bytes = decode(sum).unwrap(); - bytes + sum.parse::().unwrap().to_be_bytes().to_vec() } + _ => decode(sum).unwrap(), }; stdout().write_all(&bytes)?; return Ok(());