mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 11:37:44 +00:00
cksum: correctly output non-utf8 filename
This commit is contained in:
parent
244634b5c6
commit
6af9fd784e
2 changed files with 76 additions and 37 deletions
|
@ -19,7 +19,7 @@ use uucore::checksum::{
|
|||
use uucore::{
|
||||
encoding,
|
||||
error::{FromIo, UResult, USimpleError},
|
||||
format_usage, help_about, help_section, help_usage, show,
|
||||
format_usage, help_about, help_section, help_usage, os_str_as_bytes, show,
|
||||
sum::{div_ceil, Digest},
|
||||
};
|
||||
|
||||
|
@ -117,52 +117,64 @@ where
|
|||
};
|
||||
// The BSD checksum output is 5 digit integer
|
||||
let bsd_width = 5;
|
||||
match (options.algo_name, not_file) {
|
||||
(ALGORITHM_OPTIONS_SYSV, true) => println!(
|
||||
"{} {}",
|
||||
sum.parse::<u16>().unwrap(),
|
||||
div_ceil(sz, options.output_bits)
|
||||
),
|
||||
(ALGORITHM_OPTIONS_SYSV, false) => println!(
|
||||
let (before_filename, should_print_filename, after_filename) = match options.algo_name {
|
||||
ALGORITHM_OPTIONS_SYSV => (
|
||||
format!(
|
||||
"{} {}{}",
|
||||
sum.parse::<u16>().unwrap(),
|
||||
div_ceil(sz, options.output_bits),
|
||||
filename.display()
|
||||
if not_file { "" } else { " " }
|
||||
),
|
||||
(ALGORITHM_OPTIONS_BSD, true) => println!(
|
||||
"{:0bsd_width$} {:bsd_width$}",
|
||||
sum.parse::<u16>().unwrap(),
|
||||
div_ceil(sz, options.output_bits)
|
||||
!not_file,
|
||||
String::new(),
|
||||
),
|
||||
(ALGORITHM_OPTIONS_BSD, false) => println!(
|
||||
ALGORITHM_OPTIONS_BSD => (
|
||||
format!(
|
||||
"{:0bsd_width$} {:bsd_width$}{}",
|
||||
sum.parse::<u16>().unwrap(),
|
||||
div_ceil(sz, options.output_bits),
|
||||
filename.display()
|
||||
if not_file { "" } else { " " }
|
||||
),
|
||||
(ALGORITHM_OPTIONS_CRC, true) => println!("{sum} {sz}"),
|
||||
(ALGORITHM_OPTIONS_CRC, false) => println!("{sum} {sz} {}", filename.display()),
|
||||
(ALGORITHM_OPTIONS_BLAKE2B, _) if options.tag => {
|
||||
!not_file,
|
||||
String::new(),
|
||||
),
|
||||
ALGORITHM_OPTIONS_CRC => (
|
||||
format!("{sum} {sz}{}", if not_file { "" } else { " " }),
|
||||
!not_file,
|
||||
String::new(),
|
||||
),
|
||||
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());
|
||||
format!("BLAKE2b-{} (", length * 8)
|
||||
} else {
|
||||
println!("BLAKE2b ({}) = {sum}", filename.display());
|
||||
}
|
||||
"BLAKE2b (".to_owned()
|
||||
},
|
||||
true,
|
||||
format!(") = {sum}"),
|
||||
)
|
||||
}
|
||||
_ => {
|
||||
if options.tag {
|
||||
println!(
|
||||
"{} ({}) = {sum}",
|
||||
options.algo_name.to_ascii_uppercase(),
|
||||
filename.display()
|
||||
);
|
||||
(
|
||||
format!("{} (", options.algo_name.to_ascii_uppercase()),
|
||||
true,
|
||||
format!(") = {sum}"),
|
||||
)
|
||||
} else {
|
||||
let prefix = if options.asterisk { "*" } else { " " };
|
||||
println!("{sum} {prefix}{}", filename.display());
|
||||
(format!("{sum} {prefix}"), true, String::new())
|
||||
}
|
||||
}
|
||||
};
|
||||
print!("{}", before_filename);
|
||||
if should_print_filename {
|
||||
// The filename might not be valid UTF-8, and filename.display() would mangle the names.
|
||||
// Therefore, emit the bytes directly to stdout, without any attempt at encoding them.
|
||||
let _dropped_result = stdout().write_all(os_str_as_bytes(filename.as_os_str())?);
|
||||
}
|
||||
println!("{}", after_filename);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
//
|
||||
// For the full copyright and license information, please view the LICENSE
|
||||
// file that was distributed with this source code.
|
||||
// spell-checker:ignore (words) asdf algo algos mgmt
|
||||
// spell-checker:ignore (words) asdf algo algos asha mgmt xffname
|
||||
|
||||
use crate::common::util::TestScenario;
|
||||
|
||||
|
@ -1250,3 +1250,30 @@ fn test_several_files_error_mgmt() {
|
|||
.stderr_contains("empty: no properly ")
|
||||
.stderr_contains("incorrect: no properly ");
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[test]
|
||||
fn test_non_utf8_filename() {
|
||||
use std::ffi::OsString;
|
||||
use std::os::unix::ffi::OsStringExt;
|
||||
|
||||
let scene = TestScenario::new(util_name!());
|
||||
let at = &scene.fixtures;
|
||||
let filename: OsString = OsStringExt::from_vec(b"funky\xffname".to_vec());
|
||||
|
||||
at.touch(&filename);
|
||||
|
||||
scene
|
||||
.ucmd()
|
||||
.arg(&filename)
|
||||
.succeeds()
|
||||
.stdout_is_bytes(b"4294967295 0 funky\xffname\n")
|
||||
.no_stderr();
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("-asha256")
|
||||
.arg(filename)
|
||||
.succeeds()
|
||||
.stdout_is_bytes(b"SHA256 (funky\xffname) = e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\n")
|
||||
.no_stderr();
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue