diff --git a/src/uu/stat/src/stat.rs b/src/uu/stat/src/stat.rs index 45d3e389b..85a4bbf55 100644 --- a/src/uu/stat/src/stat.rs +++ b/src/uu/stat/src/stat.rs @@ -439,7 +439,10 @@ fn quote_file_name(file_name: &str, quoting_style: &QuotingStyle) -> String { let escaped = file_name.replace('\'', r"\'"); format!("'{escaped}'") } - QuotingStyle::ShellEscapeAlways => format!("\"{file_name}\""), + QuotingStyle::ShellEscapeAlways => { + let quote = if file_name.contains('\'') { '"' } else { '\'' }; + format!("{quote}{file_name}{quote}") + } QuotingStyle::Quote => file_name.to_string(), } } @@ -1378,7 +1381,7 @@ fn pretty_time(meta: &Metadata, md_time_field: MetadataTimeField) -> String { #[cfg(test)] mod tests { - use crate::{pad_and_print_bytes, print_padding}; + use crate::{pad_and_print_bytes, print_padding, quote_file_name}; use super::{Flags, Precision, ScanUtil, Stater, Token, group_num, precision_trunc}; @@ -1529,4 +1532,19 @@ mod tests { print_padding(&mut buffer, 5).unwrap(); assert_eq!(&buffer, b" "); } + + #[test] + fn test_quote_file_name() { + let file_name = "nice' file"; + assert_eq!( + quote_file_name(file_name, &crate::QuotingStyle::ShellEscapeAlways), + "\"nice' file\"" + ); + + let file_name = "nice\" file"; + assert_eq!( + quote_file_name(file_name, &crate::QuotingStyle::ShellEscapeAlways), + "\'nice\" file\'" + ); + } } diff --git a/tests/by-util/test_stat.rs b/tests/by-util/test_stat.rs index aeabf88fd..318735476 100644 --- a/tests/by-util/test_stat.rs +++ b/tests/by-util/test_stat.rs @@ -435,6 +435,13 @@ fn test_quoting_style_locale() { .args(&["-c", "%N", "'"]) .succeeds() .stdout_only("\"'\"\n"); + + // testing file having " + at.touch("\""); + ts.ucmd() + .args(&["-c", "%N", "\""]) + .succeeds() + .stdout_only("\'\"\'\n"); } #[test]