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

cksum: fix --binary reset (issue #6375)

This commit is contained in:
Dorian Péron 2025-02-03 01:23:28 +01:00 committed by Dorian Peron
parent 717a6921fc
commit 2fadd253f7
2 changed files with 21 additions and 118 deletions

View file

@ -205,61 +205,33 @@ mod options {
pub const ZERO: &str = "zero";
}
/// Determines whether to prompt an asterisk (*) in the output.
///
/// This function checks the `tag`, `binary`, and `had_reset` flags and returns a boolean
/// indicating whether to prompt an asterisk (*) in the output.
/// It relies on the overrides provided by clap (i.e., `--binary` overrides `--text` and vice versa).
/// Same for `--tag` and `--untagged`.
fn prompt_asterisk(tag: bool, binary: bool, had_reset: bool) -> bool {
if tag {
return false;
}
if had_reset {
return false;
}
binary
}
/**
* Determine if we had a reset.
* This is basically a hack to support the behavior of cksum
* when we have the following arguments:
* --binary --tag --untagged
* Don't do it with clap because if it struggling with the --overrides_with
* marking the value as set even if not present
*/
fn had_reset(args: &[OsString]) -> bool {
// Indices where "--binary" or "-b", "--tag", and "--untagged" are found
let binary_index = args.iter().position(|x| x == "--binary" || x == "-b");
let tag_index = args.iter().position(|x| x == "--tag");
let untagged_index = args.iter().position(|x| x == "--untagged");
// Check if all arguments are present and in the correct order
match (binary_index, tag_index, untagged_index) {
(Some(b), Some(t), Some(u)) => b < t && t < u,
_ => false,
}
}
/***
* cksum has a bunch of legacy behavior.
* We handle this in this function to make sure they are self contained
* and "easier" to understand
*/
fn handle_tag_text_binary_flags(matches: &clap::ArgMatches) -> UResult<(bool, bool)> {
let untagged = matches.get_flag(options::UNTAGGED);
let tag = matches.get_flag(options::TAG);
let tag = tag || !untagged;
fn handle_tag_text_binary_flags<S: AsRef<OsStr>>(
args: impl Iterator<Item = S>,
) -> UResult<(bool, bool)> {
let mut tag = true;
let mut binary = false;
let binary_flag = matches.get_flag(options::BINARY);
// --binary, --tag and --untagged are tight together: none of them
// conflicts with each other but --tag will reset "binary" and set "tag".
let args: Vec<OsString> = std::env::args_os().collect();
let had_reset = had_reset(&args);
for arg in args {
let arg = arg.as_ref();
if arg == "-b" || arg == "--binary" {
binary = true;
} else if arg == "--tag" {
tag = true;
binary = false;
} else if arg == "--untagged" {
tag = false;
}
}
let asterisk = prompt_asterisk(tag, binary_flag, had_reset);
Ok((tag, asterisk))
Ok((tag, !tag && binary))
}
#[uucore::main]
@ -336,7 +308,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
return perform_checksum_validation(files.iter().copied(), algo_option, length, opts);
}
let (tag, asterisk) = handle_tag_text_binary_flags(&matches)?;
let (tag, asterisk) = handle_tag_text_binary_flags(std::env::args_os())?;
let algo = detect_algo(algo_name, length)?;
let line_ending = LineEnding::from_zero_flag(matches.get_flag(options::ZERO));
@ -501,75 +473,7 @@ pub fn uu_app() -> Command {
#[cfg(test)]
mod tests {
use super::had_reset;
use crate::calculate_blake2b_length;
use crate::prompt_asterisk;
use std::ffi::OsString;
#[test]
fn test_had_reset() {
let args = ["--binary", "--tag", "--untagged"]
.iter()
.map(|&s| s.into())
.collect::<Vec<OsString>>();
assert!(had_reset(&args));
let args = ["-b", "--tag", "--untagged"]
.iter()
.map(|&s| s.into())
.collect::<Vec<OsString>>();
assert!(had_reset(&args));
let args = ["-b", "--binary", "--tag", "--untagged"]
.iter()
.map(|&s| s.into())
.collect::<Vec<OsString>>();
assert!(had_reset(&args));
let args = ["--untagged", "--tag", "--binary"]
.iter()
.map(|&s| s.into())
.collect::<Vec<OsString>>();
assert!(!had_reset(&args));
let args = ["--untagged", "--tag", "-b"]
.iter()
.map(|&s| s.into())
.collect::<Vec<OsString>>();
assert!(!had_reset(&args));
let args = ["--binary", "--tag"]
.iter()
.map(|&s| s.into())
.collect::<Vec<OsString>>();
assert!(!had_reset(&args));
let args = ["--tag", "--untagged"]
.iter()
.map(|&s| s.into())
.collect::<Vec<OsString>>();
assert!(!had_reset(&args));
let args = ["--text", "--untagged"]
.iter()
.map(|&s| s.into())
.collect::<Vec<OsString>>();
assert!(!had_reset(&args));
let args = ["--binary", "--untagged"]
.iter()
.map(|&s| s.into())
.collect::<Vec<OsString>>();
assert!(!had_reset(&args));
}
#[test]
fn test_prompt_asterisk() {
assert!(!prompt_asterisk(true, false, false));
assert!(!prompt_asterisk(false, false, true));
assert!(prompt_asterisk(false, true, false));
assert!(!prompt_asterisk(false, false, false));
}
#[test]
fn test_calculate_length() {

View file

@ -602,7 +602,6 @@ fn test_reset_binary() {
.stdout_contains("d41d8cd98f00b204e9800998ecf8427e ");
}
#[ignore = "issue #6375"]
#[test]
fn test_reset_binary_but_set() {
let scene = TestScenario::new(util_name!());
@ -619,7 +618,7 @@ fn test_reset_binary_but_set() {
.arg("--algorithm=md5")
.arg(at.subdir.join("f"))
.succeeds()
.stdout_contains("d41d8cd98f00b204e9800998ecf8427e *"); // currently, asterisk=false. It should be true
.stdout_contains("d41d8cd98f00b204e9800998ecf8427e *");
}
#[test]