Skip to content

Commit

Permalink
cksum: --tag & --untagged - the order of usage matters. manage it
Browse files Browse the repository at this point in the history
  • Loading branch information
sylvestre committed May 2, 2024
1 parent a3aee48 commit b57203c
Show file tree
Hide file tree
Showing 2 changed files with 161 additions and 22 deletions.
65 changes: 47 additions & 18 deletions src/uu/cksum/src/cksum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,10 +144,10 @@ struct Options {
algo_name: &'static str,
digest: Box<dyn Digest + 'static>,
output_bits: usize,
untagged: bool,
tag: bool, // will cover the --untagged option
length: Option<usize>,
output_format: OutputFormat,
binary: bool,
binary: bool, // will cover the --text option
}

/// Calculate checksum
Expand Down Expand Up @@ -244,7 +244,7 @@ where
),
(ALGORITHM_OPTIONS_CRC, true) => println!("{sum} {sz}"),
(ALGORITHM_OPTIONS_CRC, false) => println!("{sum} {sz} {}", filename.display()),
(ALGORITHM_OPTIONS_BLAKE2B, _) if !options.untagged => {
(ALGORITHM_OPTIONS_BLAKE2B, _) if options.tag => {
if let Some(length) = options.length {
// Multiply by 8 here, as we want to print the length in bits.
println!("BLAKE2b-{} ({}) = {sum}", length * 8, filename.display());
Expand All @@ -253,7 +253,7 @@ where
}
}
_ => {
if options.untagged {
if !options.tag {
let prefix = if options.binary { "*" } else { " " };
println!("{sum} {prefix}{}", filename.display());
} else {
Expand Down Expand Up @@ -369,22 +369,47 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
None
};

if algo_name == "bsd" && check {
let args: Vec<String> = std::env::args().collect();

// Check if --binary is present after --untagged by just reading at the order of the args
let binary_after_untagged = args
.windows(2)
.any(|pair| pair[0] == "--untagged" && (pair[1] == "--binary" || pair[1] == "-b"));

let untagged: bool = matches.get_flag(options::UNTAGGED);
let tag: bool = matches.get_flag(options::TAG);
let tag: bool = tag || !untagged;

let text_flag: bool = matches.get_flag(options::TEXT);
let binary_flag: bool = matches.get_flag(options::BINARY);

// The --binary flag is only supported with --untagged
// But it can be disabled if --binary --tag --untagged
let binary: bool = binary_flag && (!untagged || binary_after_untagged);

if tag && text_flag {
return Err(io::Error::new(
io::ErrorKind::InvalidInput,
"--check is not supported with --algorithm={bsd,sysv,crc}",
"--text mode is only supported with --untagged",
)
.into());
}

let untagged: bool = matches.get_flag(options::UNTAGGED);
let tag: bool = matches.get_flag(options::TAG);
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());
}

let binary = if untagged && tag {
false
} else {
matches.get_flag(options::BINARY)
};
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());
}

let (name, algo, bits) = detect_algo(algo_name, length);

Expand All @@ -401,7 +426,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
digest: algo,
output_bits: bits,
length,
untagged,
tag,
output_format,
binary,
};
Expand Down Expand Up @@ -451,13 +476,15 @@ pub fn uu_app() -> Command {
Arg::new(options::UNTAGGED)
.long(options::UNTAGGED)
.help("create a reversed style checksum, without digest type")
.action(ArgAction::SetTrue),
.action(ArgAction::SetTrue)
.overrides_with(options::TAG),
)
.arg(
Arg::new(options::TAG)
.long(options::TAG)
.help("create a BSD style checksum, undo --untagged (default)")
.action(ArgAction::SetTrue),
.action(ArgAction::SetTrue)
.overrides_with(options::UNTAGGED),
)
.arg(
Arg::new(options::LENGTH)
Expand Down Expand Up @@ -503,14 +530,16 @@ pub fn uu_app() -> Command {
Arg::new(options::TEXT)
.long(options::TEXT)
.short('t')
.hide(true) // for legacy compatibility, no action
.hide(true)
.overrides_with(options::BINARY)
.action(ArgAction::SetTrue),
)
.arg(
Arg::new(options::BINARY)
.long(options::BINARY)
.short('b')
.hide(true) // for legacy compatibility, no action
.hide(true)
.overrides_with(options::TEXT)
.action(ArgAction::SetTrue),
)
.after_help(AFTER_HELP)
Expand Down
118 changes: 114 additions & 4 deletions tests/by-util/test_cksum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ fn test_tag_after_untagged() {
.arg("-a=md5")
.arg("lorem_ipsum.txt")
.succeeds()
.stdout_is("cd724690f7dc61775dfac400a71f2caa lorem_ipsum.txt\n");
.stdout_is_fixture("md5_single_file.expected");
}

#[test]
Expand Down Expand Up @@ -235,10 +235,11 @@ fn test_untagged_algorithm_single_file() {
fn test_tag_short() {
new_ucmd!()
.arg("-t")
.arg("--untagged")
.arg("--algorithm=md5")
.arg("lorem_ipsum.txt")
.succeeds()
.stdout_is("MD5 (lorem_ipsum.txt) = cd724690f7dc61775dfac400a71f2caa\n");
.stdout_is("cd724690f7dc61775dfac400a71f2caa lorem_ipsum.txt\n");
}

#[test]
Expand Down Expand Up @@ -287,6 +288,22 @@ fn test_check_algo() {
.no_stdout()
.stderr_contains("cksum: --check is not supported with --algorithm={bsd,sysv,crc}")
.code_is(1);
new_ucmd!()
.arg("-a=sysv")
.arg("--check")
.arg("lorem_ipsum.txt")
.fails()
.no_stdout()
.stderr_contains("cksum: --check is not supported with --algorithm={bsd,sysv,crc}")
.code_is(1);
new_ucmd!()
.arg("-a=crc")
.arg("--check")
.arg("lorem_ipsum.txt")
.fails()
.no_stdout()
.stderr_contains("cksum: --check is not supported with --algorithm={bsd,sysv,crc}")
.code_is(1);
}

#[test]
Expand Down Expand Up @@ -455,6 +472,41 @@ fn test_all_algorithms_fail_on_folder() {
}
}

#[test]
fn test_dev_null() {
let scene = TestScenario::new(util_name!());
let at = &scene.fixtures;

at.touch("f");

scene
.ucmd()
.arg("--tag")
.arg("--untagged")
.arg("--algorithm=md5")
.arg(at.subdir.join("/dev/null"))
.succeeds()
.stdout_contains("d41d8cd98f00b204e9800998ecf8427e ");
}

#[test]
fn test_reset_binary() {
let scene = TestScenario::new(util_name!());
let at = &scene.fixtures;

at.touch("f");

scene
.ucmd()
.arg("--binary") // should disappear because of the following option
.arg("--tag")
.arg("--untagged")
.arg("--algorithm=md5")
.arg(at.subdir.join("/dev/null"))
.succeeds()
.stdout_contains("d41d8cd98f00b204e9800998ecf8427e ");
}

#[test]
fn test_binary_file() {
let scene = TestScenario::new(util_name!());
Expand All @@ -474,13 +526,40 @@ fn test_binary_file() {
// no "*" in this case
scene
.ucmd()
.arg("--untagged")
.arg("--tag")
.arg("--untagged")
.arg("--binary")
.arg("--algorithm=md5")
.arg(at.subdir.join("f"))
.succeeds()
.stdout_contains("d41d8cd98f00b204e9800998ecf8427e ");
.stdout_contains("d41d8cd98f00b204e9800998ecf8427e *");

scene
.ucmd()
.arg("--tag")
.arg("--untagged")
.arg("--binary")
.arg("--algorithm=md5")
.arg("raw/blake2b_single_file.expected")
.succeeds()
.stdout_contains("7e297c07ed8e053600092f91bdd1dad7 *");

new_ucmd!()
.arg("--tag")
.arg("--untagged")
.arg("--binary")
.arg("--algorithm=md5")
.arg("lorem_ipsum.txt")
.succeeds()
.stdout_is("cd724690f7dc61775dfac400a71f2caa *lorem_ipsum.txt\n");

new_ucmd!()
.arg("--untagged")
.arg("--binary")
.arg("--algorithm=md5")
.arg("lorem_ipsum.txt")
.succeeds()
.stdout_is("cd724690f7dc61775dfac400a71f2caa *lorem_ipsum.txt\n");
}

#[test]
Expand All @@ -500,3 +579,34 @@ fn test_folder_and_file() {
.stderr_contains(format!("cksum: {folder_name}: Is a directory"))
.stdout_is_fixture("crc_single_file.expected");
}

#[test]
fn test_conflicting_options() {
let scene = TestScenario::new(util_name!());

let at = &scene.fixtures;

at.touch("f");

scene
.ucmd()
.arg("--text")
.arg("--tag")
.arg("f")
.fails()
.no_stdout()
.stderr_contains("cksum: --text mode is only supported with --untagged")
.code_is(1);

scene
.ucmd()
.arg("--binary")
.arg("--check")
.arg("f")
.fails()
.no_stdout()
.stderr_contains(
"cksum: the --binary and --text options are meaningless when verifying checksums",
)
.code_is(1);
}

0 comments on commit b57203c

Please sign in to comment.