cksum: Fix --check filename escaping for 9.11

This commit is contained in:
Dorian Péron
2026-05-06 17:21:34 +02:00
committed by Daniel Hofstetter
parent 0ddd6f487c
commit f665b63cc4
3 changed files with 39 additions and 48 deletions
@@ -241,16 +241,16 @@ impl Display for FileChecksumResult {
/// name might contain non-utf-8 characters.
fn write_file_report<W: Write>(
mut w: W,
filename: &[u8],
filename: &OsStr,
result: FileChecksumResult,
prefix: &str,
verbose: ChecksumVerbose,
) {
) -> io::Result<()> {
if result.can_display(verbose) {
let _ = write!(w, "{prefix}");
let _ = w.write_all(filename);
let _ = writeln!(w, ": {result}");
let filename = locale_aware_escape_name(filename, QuotingStyle::SHELL_ESCAPE);
// Here, .to_string_lossy() is lossless thanks to the escaping.
writeln!(w, "{}: {result}", filename.to_string_lossy())?;
}
Ok(())
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
@@ -543,17 +543,14 @@ fn get_file_to_check(
filename: &OsStr,
opts: ChecksumValidateOptions,
) -> Result<Box<dyn Read>, LineCheckError> {
let filename_bytes = os_str_as_bytes(filename).map_err(|e| LineCheckError::UError(e.into()))?;
if filename == "-" {
Ok(Box::new(stdin())) // Use stdin if "-" is specified in the checksum file
} else {
let failed_open = || {
write_file_report(
let _ = write_file_report(
io::stdout(),
filename_bytes,
filename,
FileChecksumResult::CantOpen,
"",
opts.verbose,
);
};
@@ -686,7 +683,7 @@ fn compute_and_check_digest_from_file(
algo: SizedAlgoKind,
opts: ChecksumValidateOptions,
) -> Result<(), LineCheckError> {
let (filename_to_check_unescaped, prefix) = unescape_filename(filename);
let (filename_to_check_unescaped, _prefix) = unescape_filename(filename);
let real_filename_to_check = os_str_from_bytes(&filename_to_check_unescaped)?;
// Open the input file
@@ -708,11 +705,10 @@ fn compute_and_check_digest_from_file(
.to_string()
}));
write_file_report(
let _ = write_file_report(
io::stdout(),
filename,
&real_filename_to_check,
FileChecksumResult::CantOpen,
prefix,
opts.verbose,
);
return Err(LineCheckError::CantOpenFile);
@@ -725,11 +721,10 @@ fn compute_and_check_digest_from_file(
DigestOutput::Crc(n) => n.to_be_bytes() == expected_checksum,
DigestOutput::U16(n) => n.to_be_bytes() == expected_checksum,
};
write_file_report(
let _ = write_file_report(
io::stdout(),
filename,
&real_filename_to_check,
FileChecksumResult::from_bool(checksum_correct),
prefix,
opts.verbose,
);
@@ -1278,37 +1273,33 @@ mod tests {
fn test_write_file_report() {
let opts = ChecksumValidateOptions::default();
let cases: &[(&[u8], FileChecksumResult, &str, &[u8])] = &[
(b"filename", FileChecksumResult::Ok, "", b"filename: OK\n"),
let cases: &[(OsString, FileChecksumResult, &[u8])] = &[
(
b"filename",
OsString::from("filename"),
FileChecksumResult::Ok,
b"filename: OK\n",
),
(
OsString::from("filename"),
FileChecksumResult::Failed,
"",
b"filename: FAILED\n",
),
(
b"filename",
OsString::from("filename"),
FileChecksumResult::CantOpen,
"",
b"filename: FAILED open or read\n",
),
(
b"filename",
#[allow(clippy::unwrap_used, reason = "deterministic unwrap does not fail")]
os_str_from_bytes(b"funky\xffname").unwrap().to_os_string(),
FileChecksumResult::Ok,
"prefix",
b"prefixfilename: OK\n",
),
(
b"funky\xffname",
FileChecksumResult::Ok,
"",
b"funky\xffname: OK\n",
b"'funky'$'\\377''name': OK\n",
),
];
for (filename, result, prefix, expected) in cases {
for (filename, result, expected) in cases {
let mut buffer: Vec<u8> = vec![];
write_file_report(&mut buffer, filename, *result, prefix, opts.verbose);
let _ = write_file_report(&mut buffer, filename, *result, opts.verbose);
assert_eq!(&buffer, expected);
}
}
+5 -5
View File
@@ -1972,7 +1972,7 @@ mod check_encoding {
.arg("--check")
.arg(at.subdir.join("check"))
.succeeds()
.stdout_is_bytes(b"funky\xffname: OK\n")
.stdout_is_bytes(b"'funky'$'\\377''name': OK\n")
.no_stderr();
// Checksum mismatch
@@ -1983,7 +1983,7 @@ mod check_encoding {
.arg("--check")
.arg(at.subdir.join("check"))
.fails()
.stdout_is_bytes(b"funky\xffname: FAILED\n")
.stdout_is_bytes(b"'funky'$'\\377''name': FAILED\n")
.stderr_contains("1 computed checksum did NOT match");
// file not found
@@ -1994,7 +1994,7 @@ mod check_encoding {
.arg("--check")
.arg(at.subdir.join("check"))
.fails()
.stdout_is_bytes(b"flakey\xffname: FAILED open or read\n")
.stdout_is_bytes(b"'flakey'$'\\377''name': FAILED open or read\n")
.stderr_contains("1 listed file could not be read");
}
@@ -2015,8 +2015,8 @@ mod check_encoding {
cmd.arg("-c")
.arg("check")
.fails_with_code(1)
.stdout_contains_bytes(b"FFF\xffFFF: FAILED open or read")
.stdout_contains_bytes(b"FFF\xffDIR: FAILED open or read")
.stdout_contains_bytes(b"'FFF'$'\\377''FFF': FAILED open or read")
.stdout_contains_bytes(b"'FFF'$'\\377''DIR': FAILED open or read")
.stderr_contains("'FFF'$'\\377''FFF': No such file or directory")
.stderr_contains("'FFF'$'\\377''DIR': Is a directory");
}
+8 -8
View File
@@ -164,7 +164,7 @@ fn test_check_md5sum() {
.arg("-c")
.arg("check.md5sum")
.succeeds()
.stdout_is("a: OK\n b: OK\n*c: OK\ndd: OK\n : OK\n")
.stdout_is("a: OK\n' b': OK\n'*c': OK\ndd: OK\n' ': OK\n")
.stderr_is("");
}
#[cfg(windows)]
@@ -184,7 +184,7 @@ fn test_check_md5sum() {
.arg("-c")
.arg("check.md5sum")
.succeeds()
.stdout_is("a: OK\n b: OK\ndd: OK\n")
.stdout_is("a: OK\n' b': OK\ndd: OK\n")
.stderr_is("");
}
}
@@ -210,7 +210,7 @@ fn test_check_md5sum_only_one_space() {
.arg("-c")
.arg("check.md5sum")
.succeeds()
.stdout_only("a: OK\n b: OK\nc: OK\n");
.stdout_only("a: OK\n' b': OK\nc: OK\n");
}
#[test]
@@ -237,7 +237,7 @@ fn test_check_md5sum_reverse_bsd() {
.arg("-c")
.arg("check.md5sum")
.succeeds()
.stdout_is("a: OK\n b: OK\n*c: OK\ndd: OK\n : OK\n")
.stdout_is("a: OK\n' b': OK\n'*c': OK\ndd: OK\n' ': OK\n")
.stderr_is("");
}
#[cfg(windows)]
@@ -257,7 +257,7 @@ fn test_check_md5sum_reverse_bsd() {
.arg("-c")
.arg("check.md5sum")
.succeeds()
.stdout_is("a: OK\n b: OK\ndd: OK\n")
.stdout_is("a: OK\n' b': OK\ndd: OK\n")
.stderr_is("");
}
}
@@ -384,7 +384,7 @@ fn test_check_with_escape_filename() {
.arg("-c")
.arg("check.md5")
.succeeds();
result.stdout_is("\\a\\nb: OK\n");
result.stdout_is("'a'$'\\n''b': OK\n");
}
#[test]
@@ -510,7 +510,7 @@ fn test_check_one_two_space_star() {
.arg("--check")
.arg(at.subdir.join("in.md5"))
.fails()
.stdout_is("*empty: FAILED open or read\n");
.stdout_is("'*empty': FAILED open or read\n");
at.touch("*empty");
// Should pass as we have the file
@@ -519,7 +519,7 @@ fn test_check_one_two_space_star() {
.arg("--check")
.arg(at.subdir.join("in.md5"))
.succeeds()
.stdout_is("*empty: OK\n");
.stdout_is("'*empty': OK\n");
}
#[test]