From b301131a673515747ff790d698435b1d72fdead9 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Fri, 8 Aug 2025 10:32:27 +0200 Subject: [PATCH] dirname: fix handling of non-UTF-8 filenames --- src/uu/dirname/src/dirname.rs | 10 ++++++---- tests/by-util/test_dirname.rs | 20 ++++++++++++++++++++ 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/uu/dirname/src/dirname.rs b/src/uu/dirname/src/dirname.rs index aac8e57f3..2782c7fb3 100644 --- a/src/uu/dirname/src/dirname.rs +++ b/src/uu/dirname/src/dirname.rs @@ -4,6 +4,7 @@ // file that was distributed with this source code. use clap::{Arg, ArgAction, Command}; +use std::ffi::OsString; use std::path::Path; use uucore::LocalizedCommand; use uucore::display::print_verbatim; @@ -26,8 +27,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { let line_ending = LineEnding::from_zero_flag(matches.get_flag(options::ZERO)); - let dirnames: Vec = matches - .get_many::(options::DIR) + let dirnames: Vec = matches + .get_many::(options::DIR) .unwrap_or_default() .cloned() .collect(); @@ -47,7 +48,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { } } None => { - if p.is_absolute() || path == "/" { + if p.is_absolute() || path.as_os_str() == "/" { print!("/"); } else { print!("."); @@ -79,6 +80,7 @@ pub fn uu_app() -> Command { Arg::new(options::DIR) .hide(true) .action(ArgAction::Append) - .value_hint(clap::ValueHint::AnyPath), + .value_hint(clap::ValueHint::AnyPath) + .value_parser(clap::value_parser!(OsString)), ) } diff --git a/tests/by-util/test_dirname.rs b/tests/by-util/test_dirname.rs index e73ff2b09..933e882d7 100644 --- a/tests/by-util/test_dirname.rs +++ b/tests/by-util/test_dirname.rs @@ -64,3 +64,23 @@ fn test_pwd() { fn test_empty() { new_ucmd!().arg("").succeeds().stdout_is(".\n"); } + +#[test] +#[cfg(unix)] +fn test_dirname_non_utf8_paths() { + use std::ffi::OsStr; + use std::os::unix::ffi::OsStrExt; + + // Create a test file with non-UTF-8 bytes in the name + let non_utf8_bytes = b"test_\xFF\xFE/file.txt"; + let non_utf8_name = OsStr::from_bytes(non_utf8_bytes); + + // Test that dirname handles non-UTF-8 paths without crashing + let result = new_ucmd!().arg(non_utf8_name).succeeds(); + + // Just verify it didn't crash and produced some output + // The exact output format may vary due to lossy conversion + let output = result.stdout_str_lossy(); + assert!(!output.is_empty()); + assert!(output.contains("test_")); +}