From 2f53d594aace88e1e4ed2c28ccdf5d3e37dfd007 Mon Sep 17 00:00:00 2001 From: Nicolas Boichat Date: Tue, 22 Jul 2025 22:26:55 +0800 Subject: [PATCH] basename: Take in parameters as OSString This will allow us to handle non-Unicode strings correctly. The logic needs to be updated, next. --- src/uu/basename/src/basename.rs | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/uu/basename/src/basename.rs b/src/uu/basename/src/basename.rs index dd53522c5..2dc79aa4f 100644 --- a/src/uu/basename/src/basename.rs +++ b/src/uu/basename/src/basename.rs @@ -5,8 +5,10 @@ // spell-checker:ignore (ToDO) fullname +use clap::builder::ValueParser; use clap::{Arg, ArgAction, Command}; use std::collections::HashMap; +use std::ffi::OsString; use std::path::PathBuf; use uucore::display::Quotable; use uucore::error::{UResult, UUsageError}; @@ -24,8 +26,6 @@ pub mod options { #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { - let args = args.collect_lossy(); - // // Argument parsing // @@ -34,7 +34,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { let line_ending = LineEnding::from_zero_flag(matches.get_flag(options::ZERO)); let mut name_args = matches - .get_many::(options::NAME) + .get_many::(options::NAME) .unwrap_or_default() .collect::>(); if name_args.is_empty() { @@ -43,18 +43,18 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { get_message("basename-error-missing-operand"), )); } - let multiple_paths = - matches.get_one::(options::SUFFIX).is_some() || matches.get_flag(options::MULTIPLE); + let multiple_paths = matches.get_one::(options::SUFFIX).is_some() + || matches.get_flag(options::MULTIPLE); let suffix = if multiple_paths { matches - .get_one::(options::SUFFIX) + .get_one::(options::SUFFIX) .cloned() .unwrap_or_default() } else { // "simple format" match name_args.len() { 0 => panic!("already checked"), - 1 => String::default(), + 1 => OsString::default(), 2 => name_args.pop().unwrap().clone(), _ => { return Err(UUsageError::new( @@ -96,6 +96,7 @@ pub fn uu_app() -> Command { .arg( Arg::new(options::NAME) .action(ArgAction::Append) + .value_parser(ValueParser::os_string()) .value_hint(clap::ValueHint::AnyPath) .hide(true) .trailing_var_arg(true), @@ -105,6 +106,7 @@ pub fn uu_app() -> Command { .short('s') .long(options::SUFFIX) .value_name("SUFFIX") + .value_parser(ValueParser::os_string()) .help(get_message("basename-help-suffix")) .overrides_with(options::SUFFIX), ) @@ -118,13 +120,16 @@ pub fn uu_app() -> Command { ) } -fn basename(fullname: &str, suffix: &str) -> String { +fn basename(fullname: &OsString, suffix: &OsString) -> String { + // TODO: Remove those 2 lines. + let fullname = &fullname.to_string_lossy().to_string(); + let suffix = &suffix.to_string_lossy().to_string(); + // Handle special case where path ends with /. if fullname.ends_with("/.") { return ".".to_string(); } - // Convert to path buffer and get last path component let pb = PathBuf::from(fullname); pb.components().next_back().map_or_else(String::new, |c| {