From 98f3aacb16012b679c028155a1c33d26a6b339ee Mon Sep 17 00:00:00 2001 From: Nicolas Boichat Date: Tue, 22 Jul 2025 13:49:52 +0800 Subject: [PATCH] mkdir: Collect OsString, instead of String. collect_lossy incorrectly converts invalid UTF-8 strings, let's keep the OsString everywhere. This also means we need to modify strip_minus_from_mode to make it work with OsString. --- src/uu/mkdir/src/mkdir.rs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/uu/mkdir/src/mkdir.rs b/src/uu/mkdir/src/mkdir.rs index 4c96f42b5..3e816789e 100644 --- a/src/uu/mkdir/src/mkdir.rs +++ b/src/uu/mkdir/src/mkdir.rs @@ -10,6 +10,7 @@ use clap::parser::ValuesRef; use clap::{Arg, ArgAction, ArgMatches, Command}; use std::collections::HashMap; use std::ffi::OsString; +use std::os::unix::ffi::OsStrExt; use std::path::{Path, PathBuf}; #[cfg(not(windows))] use uucore::error::FromIo; @@ -81,7 +82,7 @@ fn get_mode(matches: &ArgMatches, mode_had_minus_prefix: bool) -> Result bool { +fn strip_minus_from_mode(_args: &mut [OsString]) -> bool { false } @@ -89,16 +90,18 @@ fn strip_minus_from_mode(_args: &mut [String]) -> bool { // of a prefix '-' if it's associated with MODE // e.g. "chmod -v -xw -R FILE" -> "chmod -v xw -R FILE" #[cfg(not(windows))] -fn strip_minus_from_mode(args: &mut Vec) -> bool { +fn strip_minus_from_mode(args: &mut Vec) -> bool { for arg in args { if arg == "--" { break; } - if let Some(arg_stripped) = arg.strip_prefix('-') { - if let Some('r' | 'w' | 'x' | 'X' | 's' | 't' | 'u' | 'g' | 'o' | '0'..='7') = - arg.chars().nth(1) + let bytes = arg.as_bytes(); + if let Some(b'-') = bytes.first() { + if let Some( + b'r' | b'w' | b'x' | b'X' | b's' | b't' | b'u' | b'g' | b'o' | b'0'..=b'7', + ) = bytes.get(1) { - *arg = arg_stripped.to_string(); + *arg = std::ffi::OsStr::from_bytes(&bytes[1..]).to_owned(); return true; } } @@ -108,7 +111,7 @@ fn strip_minus_from_mode(args: &mut Vec) -> bool { #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { - let mut args = args.collect_lossy(); + let mut args: Vec = args.collect(); // Before we can parse 'args' with clap (and previously getopts), // a possible MODE prefix '-' needs to be removed (e.g. "chmod -x FILE").