diff --git a/src/uucore/src/lib/features/checksum/validate.rs b/src/uucore/src/lib/features/checksum/validate.rs index df58c1f35ae..e9cc58a3834 100644 --- a/src/uucore/src/lib/features/checksum/validate.rs +++ b/src/uucore/src/lib/features/checksum/validate.rs @@ -241,16 +241,16 @@ impl Display for FileChecksumResult { /// name might contain non-utf-8 characters. fn write_file_report( 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, 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])] = &[ + ( + OsString::from("filename"), + FileChecksumResult::Ok, + b"filename: OK\n", + ), ( - b"filename", + 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", - FileChecksumResult::Ok, - "prefix", - b"prefixfilename: OK\n", - ), - ( - b"funky\xffname", + #[allow(clippy::unwrap_used, reason = "deterministic unwrap does not fail")] + os_str_from_bytes(b"funky\xffname").unwrap().to_os_string(), 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 = 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); } } diff --git a/tests/by-util/test_cksum.rs b/tests/by-util/test_cksum.rs index 7998ae13d8f..8f81552b3bb 100644 --- a/tests/by-util/test_cksum.rs +++ b/tests/by-util/test_cksum.rs @@ -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"); } diff --git a/tests/by-util/test_md5sum.rs b/tests/by-util/test_md5sum.rs index a7c36704ff8..773aa9ecdc8 100644 --- a/tests/by-util/test_md5sum.rs +++ b/tests/by-util/test_md5sum.rs @@ -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]