From e4024045a0e16b6ce5698a657036e75e9aa5fdca Mon Sep 17 00:00:00 2001 From: Jan Verbeek Date: Wed, 19 Nov 2025 16:13:40 +0100 Subject: [PATCH] Do not use `.display()`/`.to_string_lossy()` unnecessarily This comes up a lot for quoted strings in messages: OS strings can be quoted directly and this prevents information loss. This commit removes ~60% of the calls to these methods (modulo tests). Some of the remaining calls are benign, for example because they convert solely to check for the presence of ASCII characters. Others are nontrivial to improve. --- src/uu/base32/src/base_common.rs | 2 +- src/uu/chcon/src/chcon.rs | 4 +- src/uu/chmod/src/chmod.rs | 49 ++++++++----------- src/uu/chroot/src/chroot.rs | 6 +-- src/uu/chroot/src/error.rs | 5 +- src/uu/cksum/src/cksum.rs | 5 +- src/uu/comm/src/comm.rs | 5 +- src/uu/cp/src/cp.rs | 4 +- src/uu/cp/src/platform/macos.rs | 3 +- src/uu/cut/src/cut.rs | 4 +- src/uu/date/locales/en-US.ftl | 2 +- src/uu/date/locales/fr-FR.ftl | 2 +- src/uu/date/src/date.rs | 11 +++-- src/uu/df/src/df.rs | 2 +- src/uu/dircolors/src/dircolors.rs | 4 +- src/uu/du/locales/en-US.ftl | 2 +- src/uu/du/locales/fr-FR.ftl | 2 +- src/uu/du/src/du.rs | 10 ++-- src/uu/expand/src/expand.rs | 4 +- src/uu/hashsum/src/hashsum.rs | 6 +-- src/uu/head/src/head.rs | 11 +++-- src/uu/install/locales/en-US.ftl | 4 +- src/uu/install/locales/fr-FR.ftl | 4 +- src/uu/install/src/install.rs | 14 +++--- src/uu/join/src/join.rs | 5 +- src/uu/ln/locales/en-US.ftl | 2 +- src/uu/ln/locales/fr-FR.ftl | 2 +- src/uu/ln/src/ln.rs | 4 +- src/uu/ls/locales/en-US.ftl | 12 ++--- src/uu/ls/locales/fr-FR.ftl | 12 ++--- src/uu/ls/src/ls.rs | 16 +++--- src/uu/mkdir/src/mkdir.rs | 2 +- src/uu/mktemp/src/mktemp.rs | 16 +++--- src/uu/more/src/more.rs | 18 +++---- src/uu/mv/locales/en-US.ftl | 4 +- src/uu/mv/locales/fr-FR.ftl | 4 +- src/uu/mv/src/hardlink.rs | 26 +++++----- src/uu/mv/src/mv.rs | 4 +- src/uu/nl/src/nl.rs | 6 +-- src/uu/printf/locales/en-US.ftl | 2 +- src/uu/printf/locales/fr-FR.ftl | 2 +- src/uu/printf/src/printf.rs | 3 +- src/uu/ptx/src/ptx.rs | 4 +- src/uu/readlink/src/readlink.rs | 7 +-- src/uu/rm/locales/en-US.ftl | 2 +- src/uu/rm/locales/fr-FR.ftl | 2 +- src/uu/rm/src/rm.rs | 2 +- src/uu/sort/locales/en-US.ftl | 6 +-- src/uu/sort/locales/fr-FR.ftl | 6 +-- src/uu/sort/src/sort.rs | 8 +-- src/uu/split/src/filenames.rs | 6 +-- src/uu/split/src/split.rs | 8 +-- src/uu/sum/src/sum.rs | 4 +- src/uu/tail/locales/en-US.ftl | 2 +- src/uu/tail/locales/fr-FR.ftl | 2 +- src/uu/tail/src/args.rs | 12 +++-- src/uu/tail/src/follow/watch.rs | 2 +- src/uu/tee/src/tee.rs | 8 +-- src/uu/touch/src/touch.rs | 6 +-- src/uu/truncate/src/truncate.rs | 4 +- src/uu/tsort/src/tsort.rs | 20 ++++---- src/uu/unexpand/src/unexpand.rs | 4 +- src/uu/wc/locales/en-US.ftl | 2 +- src/uu/wc/locales/fr-FR.ftl | 2 +- src/uu/wc/src/wc.rs | 8 +-- src/uucore/locales/en-US.ftl | 8 +-- src/uucore/locales/fr-FR.ftl | 8 +-- src/uucore/src/lib/features/backup_control.rs | 5 +- src/uucore/src/lib/features/checksum.rs | 7 +-- src/uucore/src/lib/features/perms.rs | 20 +++----- src/uucore/src/lib/features/safe_traversal.rs | 31 ++++++------ src/uucore/src/lib/mods/locale.rs | 9 ++-- tests/by-util/test_chmod.rs | 4 +- tests/by-util/test_tail.rs | 4 +- 74 files changed, 256 insertions(+), 272 deletions(-) diff --git a/src/uu/base32/src/base_common.rs b/src/uu/base32/src/base_common.rs index 65cadc7c3..77882bb59 100644 --- a/src/uu/base32/src/base_common.rs +++ b/src/uu/base32/src/base_common.rs @@ -52,7 +52,7 @@ impl Config { if let Some(extra_op) = values.next() { return Err(UUsageError::new( BASE_CMD_PARSE_ERROR, - translate!("base-common-extra-operand", "operand" => extra_op.to_string_lossy().quote()), + translate!("base-common-extra-operand", "operand" => extra_op.quote()), )); } diff --git a/src/uu/chcon/src/chcon.rs b/src/uu/chcon/src/chcon.rs index 6770088e1..6069b8d2b 100644 --- a/src/uu/chcon/src/chcon.rs +++ b/src/uu/chcon/src/chcon.rs @@ -760,7 +760,7 @@ fn root_dev_ino_warn(dir_name: &Path) { } else { show_warning!( "{}", - translate!("chcon-warning-dangerous-recursive-dir", "dir" => dir_name.to_string_lossy(), "option" => options::preserve_root::NO_PRESERVE_ROOT) + translate!("chcon-warning-dangerous-recursive-dir", "dir" => dir_name.quote(), "option" => options::preserve_root::NO_PRESERVE_ROOT) ); } } @@ -782,7 +782,7 @@ fn cycle_warning_required(fts_options: c_int, entry: &fts::EntryRef) -> bool { fn emit_cycle_warning(file_name: &Path) { show_warning!( "{}", - translate!("chcon-warning-circular-directory", "file" => file_name.to_string_lossy()) + translate!("chcon-warning-circular-directory", "file" => file_name.quote()) ); } diff --git a/src/uu/chmod/src/chmod.rs b/src/uu/chmod/src/chmod.rs index c782ad429..aa012770d 100644 --- a/src/uu/chmod/src/chmod.rs +++ b/src/uu/chmod/src/chmod.rs @@ -9,7 +9,7 @@ use clap::{Arg, ArgAction, Command}; use std::ffi::OsString; use std::fs; use std::os::unix::fs::{MetadataExt, PermissionsExt}; -use std::path::Path; +use std::path::{Path, PathBuf}; use thiserror::Error; use uucore::display::Quotable; use uucore::error::{ExitCode, UError, UResult, USimpleError, UUsageError, set_exit_code}; @@ -27,17 +27,17 @@ use uucore::translate; #[derive(Debug, Error)] enum ChmodError { #[error("{}", translate!("chmod-error-cannot-stat", "file" => _0.quote()))] - CannotStat(String), + CannotStat(PathBuf), #[error("{}", translate!("chmod-error-dangling-symlink", "file" => _0.quote()))] - DanglingSymlink(String), + DanglingSymlink(PathBuf), #[error("{}", translate!("chmod-error-no-such-file", "file" => _0.quote()))] - NoSuchFile(String), + NoSuchFile(PathBuf), #[error("{}", translate!("chmod-error-preserve-root", "file" => _0.quote()))] - PreserveRoot(String), - #[error("{}", translate!("chmod-error-permission-denied", "file" => _0.quote()))] - PermissionDenied(String), - #[error("{}", translate!("chmod-error-new-permissions", "file" => _0.clone(), "actual" => _1.clone(), "expected" => _2.clone()))] - NewPermissions(String, String, String), + PreserveRoot(PathBuf), + #[error("{}", translate!("chmod-error-permission-denied", "file" => _0.maybe_quote()))] + PermissionDenied(PathBuf), + #[error("{}", translate!("chmod-error-new-permissions", "file" => _0.maybe_quote(), "actual" => _1.clone(), "expected" => _2.clone()))] + NewPermissions(PathBuf, String, String), } impl UError for ChmodError {} @@ -123,7 +123,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { Some(fref) => match fs::metadata(fref) { Ok(meta) => Some(meta.mode() & 0o7777), Err(_) => { - return Err(ChmodError::CannotStat(fref.to_string_lossy().to_string()).into()); + return Err(ChmodError::CannotStat(fref.into()).into()); } }, None => None, @@ -384,22 +384,18 @@ impl Chmoder { } if !self.quiet { - show!(ChmodError::DanglingSymlink( - filename.to_string_lossy().to_string() - )); + show!(ChmodError::DanglingSymlink(filename.into())); set_exit_code(1); } if self.verbose { println!( "{}", - translate!("chmod-verbose-failed-dangling", "file" => filename.to_string_lossy().quote()) + translate!("chmod-verbose-failed-dangling", "file" => filename.quote()) ); } } else if !self.quiet { - show!(ChmodError::NoSuchFile( - filename.to_string_lossy().to_string() - )); + show!(ChmodError::NoSuchFile(filename.into())); } // GNU exits with exit code 1 even if -q or --quiet are passed // So we set the exit code, because it hasn't been set yet if `self.quiet` is true. @@ -412,7 +408,7 @@ impl Chmoder { continue; } if self.recursive && self.preserve_root && file == Path::new("/") { - return Err(ChmodError::PreserveRoot("/".to_string()).into()); + return Err(ChmodError::PreserveRoot("/".into()).into()); } if self.recursive { r = self.walk_dir_with_context(file, true); @@ -474,10 +470,7 @@ impl Chmoder { Err(err) => { // Handle permission denied errors with proper file path context if err.kind() == std::io::ErrorKind::PermissionDenied { - r = r.and(Err(ChmodError::PermissionDenied( - file_path.to_string_lossy().to_string(), - ) - .into())); + r = r.and(Err(ChmodError::PermissionDenied(file_path.into()).into())); } else { r = r.and(Err(err.into())); } @@ -504,7 +497,7 @@ impl Chmoder { // Handle permission denied with proper file path context let e = dir_meta.unwrap_err(); let error = if e.kind() == std::io::ErrorKind::PermissionDenied { - ChmodError::PermissionDenied(entry_path.to_string_lossy().to_string()).into() + ChmodError::PermissionDenied(entry_path).into() } else { e.into() }; @@ -584,9 +577,7 @@ impl Chmoder { new_mode ); } - return Err( - ChmodError::PermissionDenied(file_path.to_string_lossy().to_string()).into(), - ); + return Err(ChmodError::PermissionDenied(file_path.into()).into()); } // Report the change using the helper method @@ -625,9 +616,9 @@ impl Chmoder { } else if err.kind() == std::io::ErrorKind::PermissionDenied { // These two filenames would normally be conditionally // quoted, but GNU's tests expect them to always be quoted - Err(ChmodError::PermissionDenied(file.to_string_lossy().to_string()).into()) + Err(ChmodError::PermissionDenied(file.into()).into()) } else { - Err(ChmodError::CannotStat(file.to_string_lossy().to_string()).into()) + Err(ChmodError::CannotStat(file.into()).into()) }; } }; @@ -657,7 +648,7 @@ impl Chmoder { // if a permission would have been removed if umask was 0, but it wasn't because umask was not 0, print an error and fail if (new_mode & !naively_expected_new_mode) != 0 { return Err(ChmodError::NewPermissions( - file.to_string_lossy().to_string(), + file.into(), display_permissions_unix(new_mode as mode_t, false), display_permissions_unix(naively_expected_new_mode as mode_t, false), ) diff --git a/src/uu/chroot/src/chroot.rs b/src/uu/chroot/src/chroot.rs index 0ac59df17..8f0a1f125 100644 --- a/src/uu/chroot/src/chroot.rs +++ b/src/uu/chroot/src/chroot.rs @@ -182,7 +182,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { } if !options.newroot.is_dir() { - return Err(ChrootError::NoSuchDirectory(format!("{}", options.newroot.display())).into()); + return Err(ChrootError::NoSuchDirectory(options.newroot).into()); } let commands = match matches.get_many::(options::COMMAND) { @@ -436,7 +436,7 @@ fn enter_chroot(root: &Path, skip_chdir: bool) -> UResult<()> { let err = unsafe { chroot( CString::new(root.as_os_str().as_bytes().to_vec()) - .map_err(|e| ChrootError::CannotEnter("root".to_string(), e.into()))? + .map_err(|e| ChrootError::CannotEnter("root".into(), e.into()))? .as_bytes_with_nul() .as_ptr() .cast::(), @@ -449,6 +449,6 @@ fn enter_chroot(root: &Path, skip_chdir: bool) -> UResult<()> { } Ok(()) } else { - Err(ChrootError::CannotEnter(format!("{}", root.display()), Error::last_os_error()).into()) + Err(ChrootError::CannotEnter(root.into(), Error::last_os_error()).into()) } } diff --git a/src/uu/chroot/src/error.rs b/src/uu/chroot/src/error.rs index 52f03ba3a..15922ad83 100644 --- a/src/uu/chroot/src/error.rs +++ b/src/uu/chroot/src/error.rs @@ -5,6 +5,7 @@ // spell-checker:ignore NEWROOT Userspec userspec //! Errors returned by chroot. use std::io::Error; +use std::path::PathBuf; use thiserror::Error; use uucore::display::Quotable; use uucore::error::UError; @@ -16,7 +17,7 @@ use uucore::translate; pub enum ChrootError { /// Failed to enter the specified directory. #[error("{}", translate!("chroot-error-cannot-enter", "dir" => _0.quote(), "err" => _1))] - CannotEnter(String, #[source] Error), + CannotEnter(PathBuf, #[source] Error), /// Failed to execute the specified command. #[error("{}", translate!("chroot-error-command-failed", "cmd" => _0.quote(), "err" => _1))] @@ -52,7 +53,7 @@ pub enum ChrootError { /// The given directory does not exist. #[error("{}", translate!("chroot-error-no-such-directory", "dir" => _0.quote()))] - NoSuchDirectory(String), + NoSuchDirectory(PathBuf), /// The call to `setgid()` failed. #[error("{}", translate!("chroot-error-set-gid-failed", "gid" => _0, "err" => _1))] diff --git a/src/uu/cksum/src/cksum.rs b/src/uu/cksum/src/cksum.rs index c7a3e969b..e755298d7 100644 --- a/src/uu/cksum/src/cksum.rs +++ b/src/uu/cksum/src/cksum.rs @@ -19,6 +19,7 @@ use uucore::checksum::{ LEGACY_ALGORITHMS, SUPPORTED_ALGORITHMS, calculate_blake2b_length_str, detect_algo, digest_reader, perform_checksum_validation, sanitize_sha2_sha3_length_str, }; +use uucore::display::Quotable; use uucore::translate; use uucore::{ @@ -200,7 +201,7 @@ where if filepath.is_dir() { show!(USimpleError::new( 1, - translate!("cksum-error-is-directory", "file" => filepath.display()) + translate!("cksum-error-is-directory", "file" => filepath.maybe_quote()) )); continue; } @@ -213,7 +214,7 @@ where file_buf = match File::open(filepath) { Ok(file) => file, Err(err) => { - show!(err.map_err_context(|| filepath.to_string_lossy().to_string())); + show!(err.map_err_context(|| filepath.maybe_quote().to_string())); continue; } }; diff --git a/src/uu/comm/src/comm.rs b/src/uu/comm/src/comm.rs index 31064fec0..80b20b53f 100644 --- a/src/uu/comm/src/comm.rs +++ b/src/uu/comm/src/comm.rs @@ -10,6 +10,7 @@ use std::ffi::OsString; use std::fs::{File, metadata}; use std::io::{self, BufRead, BufReader, Read, StdinLock, stdin}; use std::path::Path; +use uucore::display::Quotable; use uucore::error::{FromIo, UResult, USimpleError}; use uucore::format_usage; use uucore::fs::paths_refer_to_same_file; @@ -310,9 +311,9 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { let filename1 = matches.get_one::(options::FILE_1).unwrap(); let filename2 = matches.get_one::(options::FILE_2).unwrap(); let mut f1 = open_file(filename1, line_ending) - .map_err_context(|| filename1.to_string_lossy().to_string())?; + .map_err_context(|| filename1.maybe_quote().to_string())?; let mut f2 = open_file(filename2, line_ending) - .map_err_context(|| filename2.to_string_lossy().to_string())?; + .map_err_context(|| filename2.maybe_quote().to_string())?; // Due to default_value(), there must be at least one value here, thus unwrap() must not panic. let all_delimiters = matches diff --git a/src/uu/cp/src/cp.rs b/src/uu/cp/src/cp.rs index 9ef767d05..982a241b9 100644 --- a/src/uu/cp/src/cp.rs +++ b/src/uu/cp/src/cp.rs @@ -1741,13 +1741,13 @@ pub(crate) fn copy_attributes( if let Some(context) = context { if let Err(e) = context.set_for_path(dest, false, false) { return Err(CpError::Error( - translate!("cp-error-selinux-set-context", "path" => dest.display(), "error" => e), + translate!("cp-error-selinux-set-context", "path" => dest.quote(), "error" => e), )); } } } else { return Err(CpError::Error( - translate!("cp-error-selinux-get-context", "path" => source.display()), + translate!("cp-error-selinux-get-context", "path" => source.quote()), )); } Ok(()) diff --git a/src/uu/cp/src/platform/macos.rs b/src/uu/cp/src/platform/macos.rs index 226d5d710..efc00de62 100644 --- a/src/uu/cp/src/platform/macos.rs +++ b/src/uu/cp/src/platform/macos.rs @@ -10,6 +10,7 @@ use std::os::unix::fs::OpenOptionsExt; use std::path::Path; use uucore::buf_copy; +use uucore::display::Quotable; use uucore::translate; use uucore::mode::get_umask; @@ -86,7 +87,7 @@ pub(crate) fn copy_on_write( // support COW). match reflink_mode { ReflinkMode::Always => { - return Err(translate!("cp-error-failed-to-clone", "source" => source.display(), "dest" => dest.display(), "error" => error) + return Err(translate!("cp-error-failed-to-clone", "source" => source.quote(), "dest" => dest.quote(), "error" => error) .into()); } _ => { diff --git a/src/uu/cut/src/cut.rs b/src/uu/cut/src/cut.rs index b599ee45b..cc48edfab 100644 --- a/src/uu/cut/src/cut.rs +++ b/src/uu/cut/src/cut.rs @@ -374,7 +374,7 @@ fn cut_files(mut filenames: Vec, mode: &Mode) { if path.is_dir() { show_error!( "{}: {}", - filename.to_string_lossy().maybe_quote(), + filename.maybe_quote(), translate!("cut-error-is-directory") ); set_exit_code(1); @@ -383,7 +383,7 @@ fn cut_files(mut filenames: Vec, mode: &Mode) { show_if_err!( File::open(path) - .map_err_context(|| filename.to_string_lossy().to_string()) + .map_err_context(|| filename.maybe_quote().to_string()) .and_then(|file| { match &mode { Mode::Bytes(ranges, opts) | Mode::Characters(ranges, opts) => { diff --git a/src/uu/date/locales/en-US.ftl b/src/uu/date/locales/en-US.ftl index 72113c405..5935c8d22 100644 --- a/src/uu/date/locales/en-US.ftl +++ b/src/uu/date/locales/en-US.ftl @@ -99,7 +99,7 @@ date-help-universal = print or set Coordinated Universal Time (UTC) date-error-invalid-date = invalid date '{$date}' date-error-invalid-format = invalid format '{$format}' ({$error}) -date-error-expected-file-got-directory = expected file, got directory '{$path}' +date-error-expected-file-got-directory = expected file, got directory {$path} date-error-date-overflow = date overflow '{$date}' date-error-setting-date-not-supported-macos = setting the date is not supported by macOS date-error-setting-date-not-supported-redox = setting the date is not supported by Redox diff --git a/src/uu/date/locales/fr-FR.ftl b/src/uu/date/locales/fr-FR.ftl index 204121f92..c4e733c36 100644 --- a/src/uu/date/locales/fr-FR.ftl +++ b/src/uu/date/locales/fr-FR.ftl @@ -94,7 +94,7 @@ date-help-universal = afficher ou définir le Temps Universel Coordonné (UTC) date-error-invalid-date = date invalide '{$date}' date-error-invalid-format = format invalide '{$format}' ({$error}) -date-error-expected-file-got-directory = fichier attendu, répertoire obtenu '{$path}' +date-error-expected-file-got-directory = fichier attendu, répertoire obtenu {$path} date-error-date-overflow = débordement de date '{$date}' date-error-setting-date-not-supported-macos = la définition de la date n'est pas prise en charge par macOS date-error-setting-date-not-supported-redox = la définition de la date n'est pas prise en charge par Redox diff --git a/src/uu/date/src/date.rs b/src/uu/date/src/date.rs index 532125600..dd6e2028d 100644 --- a/src/uu/date/src/date.rs +++ b/src/uu/date/src/date.rs @@ -18,6 +18,7 @@ use std::fs::File; use std::io::{BufRead, BufReader}; use std::path::PathBuf; use std::sync::OnceLock; +use uucore::display::Quotable; use uucore::error::FromIo; use uucore::error::{UResult, USimpleError}; use uucore::translate; @@ -349,23 +350,23 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { if path.is_dir() { return Err(USimpleError::new( 2, - translate!("date-error-expected-file-got-directory", "path" => path.to_string_lossy()), + translate!("date-error-expected-file-got-directory", "path" => path.quote()), )); } - let file = File::open(path) - .map_err_context(|| path.as_os_str().to_string_lossy().to_string())?; + let file = + File::open(path).map_err_context(|| path.as_os_str().maybe_quote().to_string())?; let lines = BufReader::new(file).lines(); let iter = lines.map_while(Result::ok).map(parse_date); Box::new(iter) } DateSource::FileMtime(ref path) => { let metadata = std::fs::metadata(path) - .map_err_context(|| path.as_os_str().to_string_lossy().to_string())?; + .map_err_context(|| path.as_os_str().maybe_quote().to_string())?; let mtime = metadata.modified()?; let ts = Timestamp::try_from(mtime).map_err(|e| { USimpleError::new( 1, - translate!("date-error-cannot-set-date", "path" => path.to_string_lossy(), "error" => e), + translate!("date-error-cannot-set-date", "path" => path.quote(), "error" => e), ) })?; let date = ts.to_zoned(TimeZone::try_system().unwrap_or(TimeZone::UTC)); diff --git a/src/uu/df/src/df.rs b/src/uu/df/src/df.rs index 690d38d3b..d7746b915 100644 --- a/src/uu/df/src/df.rs +++ b/src/uu/df/src/df.rs @@ -370,7 +370,7 @@ where Err(FsError::InvalidPath) => { show!(USimpleError::new( 1, - translate!("df-error-no-such-file-or-directory", "path" => path.as_ref().display()) + translate!("df-error-no-such-file-or-directory", "path" => path.as_ref().maybe_quote()) )); } Err(FsError::MountMissing) => { diff --git a/src/uu/dircolors/src/dircolors.rs b/src/uu/dircolors/src/dircolors.rs index 857050bde..32e2d34a7 100644 --- a/src/uu/dircolors/src/dircolors.rs +++ b/src/uu/dircolors/src/dircolors.rs @@ -149,7 +149,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { if !files.is_empty() { return Err(UUsageError::new( 1, - translate!("dircolors-error-extra-operand-print-database", "operand" => files[0].to_string_lossy().quote()), + translate!("dircolors-error-extra-operand-print-database", "operand" => files[0].quote()), )); } @@ -198,7 +198,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { } else if files.len() > 1 { return Err(UUsageError::new( 1, - translate!("dircolors-error-extra-operand", "operand" => files[1].to_string_lossy().quote()), + translate!("dircolors-error-extra-operand", "operand" => files[1].quote()), )); } else if files[0] == "-" { let fin = BufReader::new(std::io::stdin()); diff --git a/src/uu/du/locales/en-US.ftl b/src/uu/du/locales/en-US.ftl index b503d8d53..aa8e93336 100644 --- a/src/uu/du/locales/en-US.ftl +++ b/src/uu/du/locales/en-US.ftl @@ -59,7 +59,7 @@ du-error-invalid-glob = Invalid exclude syntax: { $error } du-error-cannot-read-directory = cannot read directory { $path } du-error-cannot-access = cannot access { $path } du-error-read-error-is-directory = { $file }: read error: Is a directory -du-error-cannot-open-for-reading = cannot open '{ $file }' for reading: No such file or directory +du-error-cannot-open-for-reading = cannot open { $file } for reading: No such file or directory du-error-invalid-zero-length-file-name = { $file }:{ $line }: invalid zero-length file name du-error-extra-operand-with-files0-from = extra operand { $file } file operands cannot be combined with --files0-from diff --git a/src/uu/du/locales/fr-FR.ftl b/src/uu/du/locales/fr-FR.ftl index e89385213..ff855ab85 100644 --- a/src/uu/du/locales/fr-FR.ftl +++ b/src/uu/du/locales/fr-FR.ftl @@ -59,7 +59,7 @@ du-error-invalid-glob = Syntaxe d'exclusion invalide : { $error } du-error-cannot-read-directory = impossible de lire le répertoire { $path } du-error-cannot-access = impossible d'accéder à { $path } du-error-read-error-is-directory = { $file } : erreur de lecture : C'est un répertoire -du-error-cannot-open-for-reading = impossible d'ouvrir '{ $file }' en lecture : Aucun fichier ou répertoire de ce type +du-error-cannot-open-for-reading = impossible d'ouvrir { $file } en lecture : Aucun fichier ou répertoire de ce type du-error-invalid-zero-length-file-name = { $file }:{ $line } : nom de fichier de longueur zéro invalide du-error-extra-operand-with-files0-from = opérande supplémentaire { $file } les opérandes de fichier ne peuvent pas être combinées avec --files0-from diff --git a/src/uu/du/src/du.rs b/src/uu/du/src/du.rs index 4c29d07d3..8625f10cc 100644 --- a/src/uu/du/src/du.rs +++ b/src/uu/du/src/du.rs @@ -914,7 +914,7 @@ fn read_files_from(file_name: &OsStr) -> Result, std::io::Error> { let path = PathBuf::from(file_name); if path.is_dir() { return Err(std::io::Error::other( - translate!("du-error-read-error-is-directory", "file" => file_name.to_string_lossy()), + translate!("du-error-read-error-is-directory", "file" => file_name.maybe_quote()), )); } @@ -923,7 +923,7 @@ fn read_files_from(file_name: &OsStr) -> Result, std::io::Error> { Ok(file) => Box::new(BufReader::new(file)), Err(e) if e.kind() == std::io::ErrorKind::NotFound => { return Err(std::io::Error::other( - translate!("du-error-cannot-open-for-reading", "file" => file_name.to_string_lossy()), + translate!("du-error-cannot-open-for-reading", "file" => file_name.quote()), )); } Err(e) => return Err(e), @@ -939,7 +939,7 @@ fn read_files_from(file_name: &OsStr) -> Result, std::io::Error> { let line_number = i + 1; show_error!( "{}", - translate!("du-error-invalid-zero-length-file-name", "file" => file_name.to_string_lossy(), "line" => line_number) + translate!("du-error-invalid-zero-length-file-name", "file" => file_name.maybe_quote(), "line" => line_number) ); set_exit_code(1); } else { @@ -976,7 +976,6 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { "file" => matches .get_one::(options::FILE) .unwrap() - .to_string_lossy() .quote() ), ) @@ -1169,7 +1168,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { #[cfg(target_os = "linux")] let error_msg = translate!("du-error-cannot-access", "path" => path.quote()); #[cfg(not(target_os = "linux"))] - let error_msg = translate!("du-error-cannot-access-no-such-file", "path" => path.to_string_lossy().quote()); + let error_msg = + translate!("du-error-cannot-access-no-such-file", "path" => path.quote()); print_tx .send(Err(USimpleError::new(1, error_msg))) diff --git a/src/uu/expand/src/expand.rs b/src/uu/expand/src/expand.rs index f6289a573..294b3bc88 100644 --- a/src/uu/expand/src/expand.rs +++ b/src/uu/expand/src/expand.rs @@ -296,7 +296,7 @@ fn open(path: &OsString) -> UResult>> { Ok(BufReader::new(Box::new(stdin()) as Box)) } else { let path_ref = Path::new(path); - file_buf = File::open(path_ref).map_err_context(|| path.to_string_lossy().to_string())?; + file_buf = File::open(path_ref).map_err_context(|| path.maybe_quote().to_string())?; Ok(BufReader::new(Box::new(file_buf) as Box)) } } @@ -458,7 +458,7 @@ fn expand(options: &Options) -> UResult<()> { if Path::new(file).is_dir() { show_error!( "{}", - translate!("expand-error-is-directory", "file" => file.to_string_lossy()) + translate!("expand-error-is-directory", "file" => file.maybe_quote()) ); set_exit_code(1); continue; diff --git a/src/uu/hashsum/src/hashsum.rs b/src/uu/hashsum/src/hashsum.rs index 4f3ac34cb..0f591c0dc 100644 --- a/src/uu/hashsum/src/hashsum.rs +++ b/src/uu/hashsum/src/hashsum.rs @@ -25,7 +25,7 @@ use uucore::checksum::detect_algo; use uucore::checksum::digest_reader; use uucore::checksum::escape_filename; use uucore::checksum::perform_checksum_validation; -use uucore::display::print_verbatim; +use uucore::display::{Quotable, print_verbatim}; use uucore::error::{UResult, strip_errno}; use uucore::format_usage; use uucore::sum::{Digest, Sha3_224, Sha3_256, Sha3_384, Sha3_512, Shake128, Shake256}; @@ -546,7 +546,7 @@ where eprintln!( "{}: {}: {}", options.binary_name, - filename.to_string_lossy(), + filename.maybe_quote(), strip_errno(&e) ); err_found = Some(ChecksumError::Io(e)); @@ -568,7 +568,7 @@ where eprintln!( "{}: {}: {}", options.binary_name, - filename.to_string_lossy(), + filename.maybe_quote(), strip_errno(&e) ); err_found = Some(ChecksumError::Io(e)); diff --git a/src/uu/head/src/head.rs b/src/uu/head/src/head.rs index 6f8fe57b6..7bb076c7f 100644 --- a/src/uu/head/src/head.rs +++ b/src/uu/head/src/head.rs @@ -13,6 +13,7 @@ use std::io::{self, BufWriter, Read, Seek, SeekFrom, Write}; use std::num::TryFromIntError; #[cfg(unix)] use std::os::fd::{AsRawFd, FromRawFd}; +use std::path::PathBuf; use thiserror::Error; use uucore::display::{Quotable, print_verbatim}; use uucore::error::{FromIo, UError, UResult}; @@ -41,8 +42,8 @@ use take::take_lines; #[derive(Error, Debug)] enum HeadError { /// Wrapper around `io::Error` - #[error("{}", translate!("head-error-reading-file", "name" => name.clone(), "err" => err))] - Io { name: String, err: io::Error }, + #[error("{}", translate!("head-error-reading-file", "name" => name.quote(), "err" => err))] + Io { name: PathBuf, err: io::Error }, #[error("{}", translate!("head-error-parse-error", "err" => 0))] ParseError(String), @@ -513,7 +514,7 @@ fn uu_head(options: &HeadOptions) -> UResult<()> { Ok(f) => f, Err(err) => { show!(err.map_err_context( - || translate!("head-error-cannot-open", "name" => file.to_string_lossy().quote()) + || translate!("head-error-cannot-open", "name" => file.quote()) )); continue; } @@ -531,9 +532,9 @@ fn uu_head(options: &HeadOptions) -> UResult<()> { }; if let Err(err) = res { let name = if file == "-" { - "standard input".to_string() + "standard input".into() } else { - file.to_string_lossy().into_owned() + file.into() }; return Err(HeadError::Io { name, err }.into()); } diff --git a/src/uu/install/locales/en-US.ftl b/src/uu/install/locales/en-US.ftl index 344301666..e68d469ec 100644 --- a/src/uu/install/locales/en-US.ftl +++ b/src/uu/install/locales/en-US.ftl @@ -38,7 +38,7 @@ install-error-invalid-group = invalid group: { $group } install-error-omitting-directory = omitting directory { $path } install-error-not-a-directory = failed to access { $path }: Not a directory install-error-override-directory-failed = cannot overwrite directory { $dir } with non-directory { $file } -install-error-same-file = '{ $file1 }' and '{ $file2 }' are the same file +install-error-same-file = { $file1 } and { $file2 } are the same file install-error-extra-operand = extra operand { $operand } { $usage } install-error-invalid-mode = Invalid mode string: { $error } @@ -46,7 +46,7 @@ install-error-mutually-exclusive-target = Options --target-directory and --no-ta install-error-mutually-exclusive-compare-preserve = Options --compare and --preserve-timestamps are mutually exclusive install-error-mutually-exclusive-compare-strip = Options --compare and --strip are mutually exclusive install-error-missing-file-operand = missing file operand -install-error-missing-destination-operand = missing destination file operand after '{ $path }' +install-error-missing-destination-operand = missing destination file operand after { $path } install-error-failed-to-remove = Failed to remove existing file { $path }. Error: { $error } # Warning messages diff --git a/src/uu/install/locales/fr-FR.ftl b/src/uu/install/locales/fr-FR.ftl index 0a28d9a6f..72c7c4f67 100644 --- a/src/uu/install/locales/fr-FR.ftl +++ b/src/uu/install/locales/fr-FR.ftl @@ -38,7 +38,7 @@ install-error-invalid-group = groupe invalide : { $group } install-error-omitting-directory = omission du répertoire { $path } install-error-not-a-directory = échec de l'accès à { $path } : N'est pas un répertoire install-error-override-directory-failed = impossible d'écraser le répertoire { $dir } avec un non-répertoire { $file } -install-error-same-file = '{ $file1 }' et '{ $file2 }' sont le même fichier +install-error-same-file = { $file1 } et { $file2 } sont le même fichier install-error-extra-operand = opérande supplémentaire { $operand } { $usage } install-error-invalid-mode = Chaîne de mode invalide : { $error } @@ -46,7 +46,7 @@ install-error-mutually-exclusive-target = Les options --target-directory et --no install-error-mutually-exclusive-compare-preserve = Les options --compare et --preserve-timestamps sont mutuellement exclusives install-error-mutually-exclusive-compare-strip = Les options --compare et --strip sont mutuellement exclusives install-error-missing-file-operand = opérande de fichier manquant -install-error-missing-destination-operand = opérande de fichier de destination manquant après '{ $path }' +install-error-missing-destination-operand = opérande de fichier de destination manquant après { $path } install-error-failed-to-remove = Échec de la suppression du fichier existant { $path }. Erreur : { $error } # Messages d'avertissement diff --git a/src/uu/install/src/install.rs b/src/uu/install/src/install.rs index 49252dcf9..724ed4e96 100644 --- a/src/uu/install/src/install.rs +++ b/src/uu/install/src/install.rs @@ -84,10 +84,10 @@ enum InstallError { #[error("{}", translate!("install-error-target-not-dir", "path" => .0.quote()))] TargetDirIsntDir(PathBuf), - #[error("{}", translate!("install-error-backup-failed", "from" => .0.to_string_lossy(), "to" => .1.to_string_lossy()))] + #[error("{}", translate!("install-error-backup-failed", "from" => .0.quote(), "to" => .1.quote()))] BackupFailed(PathBuf, PathBuf, #[source] std::io::Error), - #[error("{}", translate!("install-error-install-failed", "from" => .0.to_string_lossy(), "to" => .1.to_string_lossy()))] + #[error("{}", translate!("install-error-install-failed", "from" => .0.quote(), "to" => .1.quote()))] InstallFailed(PathBuf, PathBuf, #[source] std::io::Error), #[error("{}", translate!("install-error-strip-failed", "error" => .0.clone()))] @@ -111,11 +111,11 @@ enum InstallError { #[error("{}", translate!("install-error-override-directory-failed", "dir" => .0.quote(), "file" => .1.quote()))] OverrideDirectoryFailed(PathBuf, PathBuf), - #[error("{}", translate!("install-error-same-file", "file1" => .0.to_string_lossy(), "file2" => .1.to_string_lossy()))] + #[error("{}", translate!("install-error-same-file", "file1" => .0.quote(), "file2" => .1.quote()))] SameFile(PathBuf, PathBuf), #[error("{}", translate!("install-error-extra-operand", "operand" => .0.quote(), "usage" => .1.clone()))] - ExtraOperand(String, String), + ExtraOperand(OsString, String), #[cfg(feature = "selinux")] #[error("{}", .0)] @@ -554,7 +554,7 @@ fn standard(mut paths: Vec, b: &Behavior) -> UResult<()> { } if b.no_target_dir && paths.len() > 2 { return Err(InstallError::ExtraOperand( - paths[2].to_string_lossy().into_owned(), + paths[2].clone(), format_usage(&translate!("install-usage")), ) .into()); @@ -570,7 +570,7 @@ fn standard(mut paths: Vec, b: &Behavior) -> UResult<()> { if paths.is_empty() { return Err(UUsageError::new( 1, - translate!("install-error-missing-destination-operand", "path" => last_path.to_string_lossy()), + translate!("install-error-missing-destination-operand", "path" => last_path.quote()), )); } @@ -835,7 +835,7 @@ fn copy_file(from: &Path, to: &Path) -> UResult<()> { if e.kind() != std::io::ErrorKind::NotFound { show_error!( "{}", - translate!("install-error-failed-to-remove", "path" => to.display(), "error" => format!("{e:?}")) + translate!("install-error-failed-to-remove", "path" => to.quote(), "error" => format!("{e:?}")) ); } } diff --git a/src/uu/join/src/join.rs b/src/uu/join/src/join.rs index 58d83fc40..1360e4a6a 100644 --- a/src/uu/join/src/join.rs +++ b/src/uu/join/src/join.rs @@ -435,8 +435,7 @@ impl<'a> State<'a> { let file_buf = if name == "-" { Box::new(stdin.lock()) as Box } else { - let file = File::open(name) - .map_err_context(|| format!("{}", name.to_string_lossy().maybe_quote()))?; + let file = File::open(name).map_err_context(|| format!("{}", name.maybe_quote()))?; Box::new(BufReader::new(file)) as Box }; @@ -639,7 +638,7 @@ impl<'a> State<'a> { && (input.check_order == CheckOrder::Enabled || (self.has_unpaired && !self.has_failed)) { - let err_msg = translate!("join-error-not-sorted", "file" => self.file_name.to_string_lossy().maybe_quote(), "line_num" => self.line_num, "content" => String::from_utf8_lossy(&line.string)); + let err_msg = translate!("join-error-not-sorted", "file" => self.file_name.maybe_quote(), "line_num" => self.line_num, "content" => String::from_utf8_lossy(&line.string)); // This is fatal if the check is enabled. if input.check_order == CheckOrder::Enabled { return Err(JoinError::UnorderedInput(err_msg)); diff --git a/src/uu/ln/locales/en-US.ftl b/src/uu/ln/locales/en-US.ftl index 85315070d..1873ef744 100644 --- a/src/uu/ln/locales/en-US.ftl +++ b/src/uu/ln/locales/en-US.ftl @@ -30,7 +30,7 @@ ln-error-extra-operand = extra operand {$operand} Try '{$program} --help' for more information. ln-error-could-not-update = Could not update {$target}: {$error} ln-error-cannot-stat = cannot stat {$path}: No such file or directory -ln-error-will-not-overwrite = will not overwrite just-created '{$target}' with '{$source}' +ln-error-will-not-overwrite = will not overwrite just-created {$target} with {$source} ln-prompt-replace = replace {$file}? ln-cannot-backup = cannot backup {$file} ln-failed-to-access = failed to access {$file} diff --git a/src/uu/ln/locales/fr-FR.ftl b/src/uu/ln/locales/fr-FR.ftl index 483f15c92..b9e246798 100644 --- a/src/uu/ln/locales/fr-FR.ftl +++ b/src/uu/ln/locales/fr-FR.ftl @@ -31,7 +31,7 @@ ln-error-extra-operand = opérande supplémentaire {$operand} Essayez « {$program} --help » pour plus d'informations. ln-error-could-not-update = Impossible de mettre à jour {$target} : {$error} ln-error-cannot-stat = impossible d'analyser {$path} : Aucun fichier ou répertoire de ce nom -ln-error-will-not-overwrite = ne remplacera pas le fichier « {$target} » qui vient d'être créé par « {$source} » +ln-error-will-not-overwrite = ne remplacera pas le fichier {$target} qui vient d'être créé par {$source} ln-prompt-replace = remplacer {$file} ? ln-cannot-backup = impossible de sauvegarder {$file} ln-failed-to-access = échec d'accès à {$file} diff --git a/src/uu/ln/src/ln.rs b/src/uu/ln/src/ln.rs index a3fde8f4a..9abf4fb00 100644 --- a/src/uu/ln/src/ln.rs +++ b/src/uu/ln/src/ln.rs @@ -60,7 +60,7 @@ enum LnError { #[error("{}", translate!("ln-error-missing-destination", "operand" => _0.quote()))] MissingDestination(PathBuf), - #[error("{}", translate!("ln-error-extra-operand", "operand" => _0.to_string_lossy(), "program" => _1.clone()))] + #[error("{}", translate!("ln-error-extra-operand", "operand" => _0.quote(), "program" => _1.clone()))] ExtraOperand(OsString, String), } @@ -342,7 +342,7 @@ fn link_files_in_dir(files: &[PathBuf], target_dir: &Path, settings: &Settings) // If the target file was already created in this ln call, do not overwrite show_error!( "{}", - translate!("ln-error-will-not-overwrite", "target" => targetpath.display(), "source" => srcpath.display()) + translate!("ln-error-will-not-overwrite", "target" => targetpath.quote(), "source" => srcpath.quote()) ); all_successful = false; } else if let Err(e) = link(srcpath, &targetpath, settings) { diff --git a/src/uu/ls/locales/en-US.ftl b/src/uu/ls/locales/en-US.ftl index b8cad5858..03e1e2642 100644 --- a/src/uu/ls/locales/en-US.ftl +++ b/src/uu/ls/locales/en-US.ftl @@ -6,12 +6,12 @@ ls-after-help = The TIME_STYLE argument can be full-iso, long-iso, iso, locale o # Error messages ls-error-invalid-line-width = invalid line width: {$width} ls-error-general-io = general io error: {$error} -ls-error-cannot-access-no-such-file = cannot access '{$path}': No such file or directory -ls-error-cannot-access-operation-not-permitted = cannot access '{$path}': Operation not permitted -ls-error-cannot-open-directory-permission-denied = cannot open directory '{$path}': Permission denied -ls-error-cannot-open-file-permission-denied = cannot open file '{$path}': Permission denied -ls-error-cannot-open-directory-bad-descriptor = cannot open directory '{$path}': Bad file descriptor -ls-error-unknown-io-error = unknown io error: '{$path}', '{$error}' +ls-error-cannot-access-no-such-file = cannot access {$path}: No such file or directory +ls-error-cannot-access-operation-not-permitted = cannot access {$path}: Operation not permitted +ls-error-cannot-open-directory-permission-denied = cannot open directory {$path}: Permission denied +ls-error-cannot-open-file-permission-denied = cannot open file {$path}: Permission denied +ls-error-cannot-open-directory-bad-descriptor = cannot open directory {$path}: Bad file descriptor +ls-error-unknown-io-error = unknown io error: {$path}, '{$error}' ls-error-invalid-block-size = invalid --block-size argument {$size} ls-error-dired-and-zero-incompatible = --dired and --zero are incompatible ls-error-not-listing-already-listed = {$path}: not listing already-listed directory diff --git a/src/uu/ls/locales/fr-FR.ftl b/src/uu/ls/locales/fr-FR.ftl index 40dd3877c..552e4095f 100644 --- a/src/uu/ls/locales/fr-FR.ftl +++ b/src/uu/ls/locales/fr-FR.ftl @@ -6,12 +6,12 @@ ls-after-help = L'argument TIME_STYLE peut être full-iso, long-iso, iso, locale # Messages d'erreur ls-error-invalid-line-width = largeur de ligne invalide : {$width} ls-error-general-io = erreur d'E/S générale : {$error} -ls-error-cannot-access-no-such-file = impossible d'accéder à '{$path}' : Aucun fichier ou répertoire de ce type -ls-error-cannot-access-operation-not-permitted = impossible d'accéder à '{$path}' : Opération non autorisée -ls-error-cannot-open-directory-permission-denied = impossible d'ouvrir le répertoire '{$path}' : Permission refusée -ls-error-cannot-open-file-permission-denied = impossible d'ouvrir le fichier '{$path}' : Permission refusée -ls-error-cannot-open-directory-bad-descriptor = impossible d'ouvrir le répertoire '{$path}' : Mauvais descripteur de fichier -ls-error-unknown-io-error = erreur d'E/S inconnue : '{$path}', '{$error}' +ls-error-cannot-access-no-such-file = impossible d'accéder à {$path} : Aucun fichier ou répertoire de ce type +ls-error-cannot-access-operation-not-permitted = impossible d'accéder à {$path} : Opération non autorisée +ls-error-cannot-open-directory-permission-denied = impossible d'ouvrir le répertoire {$path} : Permission refusée +ls-error-cannot-open-file-permission-denied = impossible d'ouvrir le fichier {$path} : Permission refusée +ls-error-cannot-open-directory-bad-descriptor = impossible d'ouvrir le répertoire {$path} : Mauvais descripteur de fichier +ls-error-unknown-io-error = erreur d'E/S inconnue : {$path}, '{$error}' ls-error-invalid-block-size = argument --block-size invalide {$size} ls-error-dired-and-zero-incompatible = --dired et --zero sont incompatibles ls-error-not-listing-already-listed = {$path} : ne liste pas un répertoire déjà listé diff --git a/src/uu/ls/src/ls.rs b/src/uu/ls/src/ls.rs index 6f038142a..8f60bd46e 100644 --- a/src/uu/ls/src/ls.rs +++ b/src/uu/ls/src/ls.rs @@ -184,18 +184,18 @@ enum LsError { IOError(#[from] std::io::Error), #[error("{}", match .1.kind() { - ErrorKind::NotFound => translate!("ls-error-cannot-access-no-such-file", "path" => .0.to_string_lossy()), + ErrorKind::NotFound => translate!("ls-error-cannot-access-no-such-file", "path" => .0.quote()), ErrorKind::PermissionDenied => match .1.raw_os_error().unwrap_or(1) { - 1 => translate!("ls-error-cannot-access-operation-not-permitted", "path" => .0.to_string_lossy()), + 1 => translate!("ls-error-cannot-access-operation-not-permitted", "path" => .0.quote()), _ => if .0.is_dir() { - translate!("ls-error-cannot-open-directory-permission-denied", "path" => .0.to_string_lossy()) + translate!("ls-error-cannot-open-directory-permission-denied", "path" => .0.quote()) } else { - translate!("ls-error-cannot-open-file-permission-denied", "path" => .0.to_string_lossy()) + translate!("ls-error-cannot-open-file-permission-denied", "path" => .0.quote()) }, }, _ => match .1.raw_os_error().unwrap_or(1) { - 9 => translate!("ls-error-cannot-open-directory-bad-descriptor", "path" => .0.to_string_lossy()), - _ => translate!("ls-error-unknown-io-error", "path" => .0.to_string_lossy(), "error" => format!("{:?}", .1)), + 9 => translate!("ls-error-cannot-open-directory-bad-descriptor", "path" => .0.quote()), + _ => translate!("ls-error-unknown-io-error", "path" => .0.quote(), "error" => format!("{:?}", .1)), }, })] IOErrorContext(PathBuf, std::io::Error, bool), @@ -206,7 +206,7 @@ enum LsError { #[error("{}", translate!("ls-error-dired-and-zero-incompatible"))] DiredAndZeroAreIncompatible, - #[error("{}", translate!("ls-error-not-listing-already-listed", "path" => .0.to_string_lossy()))] + #[error("{}", translate!("ls-error-not-listing-already-listed", "path" => .0.quote()))] AlreadyListedError(PathBuf), #[error("{}", translate!("ls-error-invalid-time-style", "style" => .0.quote()))] @@ -2392,7 +2392,7 @@ fn enter_directory( // 2 = \n + \n dired.padding = 2; dired::indent(&mut state.out)?; - let dir_name_size = e.path().to_string_lossy().len(); + let dir_name_size = e.path().as_os_str().len(); dired::calculate_subdired(dired, dir_name_size); // inject dir name dired::add_dir_name(dired, dir_name_size); diff --git a/src/uu/mkdir/src/mkdir.rs b/src/uu/mkdir/src/mkdir.rs index a16be0c26..b6b0d025c 100644 --- a/src/uu/mkdir/src/mkdir.rs +++ b/src/uu/mkdir/src/mkdir.rs @@ -223,7 +223,7 @@ fn create_dir(path: &Path, is_parent: bool, config: &Config) -> UResult<()> { if path_exists && !config.recursive { return Err(USimpleError::new( 1, - translate!("mkdir-error-file-exists", "path" => path.to_string_lossy()), + translate!("mkdir-error-file-exists", "path" => path.maybe_quote()), )); } if path == Path::new("") { diff --git a/src/uu/mktemp/src/mktemp.rs b/src/uu/mktemp/src/mktemp.rs index a0eaa32d4..c285e9c90 100644 --- a/src/uu/mktemp/src/mktemp.rs +++ b/src/uu/mktemp/src/mktemp.rs @@ -62,13 +62,13 @@ enum MkTempError { SuffixContainsDirSeparator(String), #[error("{}", translate!("mktemp-error-invalid-template", "template" => .0.quote()))] - InvalidTemplate(String), + InvalidTemplate(OsString), #[error("{}", translate!("mktemp-error-too-many-templates"))] TooManyTemplates, #[error("{}", translate!("mktemp-error-not-found", "template_type" => .0.clone(), "template" => .1.quote()))] - NotFound(String, String), + NotFound(String, PathBuf), } impl UError for MkTempError { @@ -203,9 +203,7 @@ impl Params { // Convert OsString template to string for processing let Some(template_str) = options.template.to_str() else { // For non-UTF-8 templates, return an error - return Err(MkTempError::InvalidTemplate( - options.template.to_string_lossy().into_owned(), - )); + return Err(MkTempError::InvalidTemplate(options.template)); }; // The template argument must end in 'X' if a suffix option is given. @@ -242,7 +240,7 @@ impl Params { )); } if tmpdir.is_some() && Path::new(prefix_from_template).is_absolute() { - return Err(MkTempError::InvalidTemplate(template_str.to_string())); + return Err(MkTempError::InvalidTemplate(template_str.into())); } // Split the parent directory from the file part of the prefix. @@ -527,8 +525,7 @@ fn make_temp_dir(dir: &Path, prefix: &str, rand: usize, suffix: &str) -> UResult Err(e) if e.kind() == ErrorKind::NotFound => { let filename = format!("{prefix}{}{suffix}", "X".repeat(rand)); let path = Path::new(dir).join(filename); - let s = path.display().to_string(); - Err(MkTempError::NotFound(translate!("mktemp-template-type-directory"), s).into()) + Err(MkTempError::NotFound(translate!("mktemp-template-type-directory"), path).into()) } Err(e) => Err(e.into()), } @@ -557,8 +554,7 @@ fn make_temp_file(dir: &Path, prefix: &str, rand: usize, suffix: &str) -> UResul Err(e) if e.kind() == ErrorKind::NotFound => { let filename = format!("{prefix}{}{suffix}", "X".repeat(rand)); let path = Path::new(dir).join(filename); - let s = path.display().to_string(); - Err(MkTempError::NotFound(translate!("mktemp-template-type-file"), s).into()) + Err(MkTempError::NotFound(translate!("mktemp-template-type-file"), path).into()) } Err(e) => Err(e.into()), } diff --git a/src/uu/more/src/more.rs b/src/uu/more/src/more.rs index 796a1469f..e882f4028 100644 --- a/src/uu/more/src/more.rs +++ b/src/uu/more/src/more.rs @@ -8,7 +8,7 @@ use std::{ fs::File, io::{BufRead, BufReader, Stdin, Stdout, Write, stdin, stdout}, panic::set_hook, - path::Path, + path::{Path, PathBuf}, time::Duration, }; @@ -31,9 +31,9 @@ use uucore::translate; #[derive(Debug)] enum MoreError { - IsDirectory(String), - CannotOpenNoSuchFile(String), - CannotOpenIOError(String, std::io::ErrorKind), + IsDirectory(PathBuf), + CannotOpenNoSuchFile(PathBuf), + CannotOpenIOError(PathBuf, std::io::ErrorKind), BadUsage, } @@ -163,14 +163,14 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { if file.is_dir() { show!(UUsageError::new( 0, - MoreError::IsDirectory(file.to_string_lossy().to_string()).to_string(), + MoreError::IsDirectory(file.into()).to_string(), )); continue; } if !file.exists() { show!(USimpleError::new( 0, - MoreError::CannotOpenNoSuchFile(file.to_string_lossy().to_string()).to_string(), + MoreError::CannotOpenNoSuchFile(file.into()).to_string(), )); continue; } @@ -178,11 +178,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { Err(why) => { show!(USimpleError::new( 0, - MoreError::CannotOpenIOError( - file.to_string_lossy().to_string(), - why.kind() - ) - .to_string(), + MoreError::CannotOpenIOError(file.into(), why.kind()).to_string(), )); continue; } diff --git a/src/uu/mv/locales/en-US.ftl b/src/uu/mv/locales/en-US.ftl index fda4ea224..39ca2d853 100644 --- a/src/uu/mv/locales/en-US.ftl +++ b/src/uu/mv/locales/en-US.ftl @@ -29,14 +29,14 @@ mv-error-failed-access-not-directory = failed to access {$path}: Not a directory mv-error-backup-with-no-clobber = cannot combine --backup with -n/--no-clobber or --update=none-fail mv-error-extra-operand = mv: extra operand {$operand} mv-error-backup-might-destroy-source = backing up {$target} might destroy source; {$source} not moved -mv-error-will-not-overwrite-just-created = will not overwrite just-created '{$target}' with '{$source}' +mv-error-will-not-overwrite-just-created = will not overwrite just-created {$target} with {$source} mv-error-not-replacing = not replacing {$target} mv-error-cannot-move = cannot move {$source} to {$target} mv-error-directory-not-empty = Directory not empty mv-error-dangling-symlink = can't determine symlink type, since it is dangling mv-error-no-symlink-support = your operating system does not support symlinks mv-error-permission-denied = Permission denied -mv-error-inter-device-move-failed = inter-device move failed: '{$from}' to '{$to}'; unable to remove target: {$err} +mv-error-inter-device-move-failed = inter-device move failed: {$from} to {$to}; unable to remove target: {$err} # Help messages mv-help-force = do not prompt before overwriting diff --git a/src/uu/mv/locales/fr-FR.ftl b/src/uu/mv/locales/fr-FR.ftl index 2288e95f5..9ea2f2114 100644 --- a/src/uu/mv/locales/fr-FR.ftl +++ b/src/uu/mv/locales/fr-FR.ftl @@ -29,14 +29,14 @@ mv-error-failed-access-not-directory = impossible d'accéder à {$path} : N'est mv-error-backup-with-no-clobber = impossible de combiner --backup avec -n/--no-clobber ou --update=none-fail mv-error-extra-operand = mv : opérande supplémentaire {$operand} mv-error-backup-might-destroy-source = sauvegarder {$target} pourrait détruire la source ; {$source} non déplacé -mv-error-will-not-overwrite-just-created = ne va pas écraser le fichier qui vient d'être créé '{$target}' avec '{$source}' +mv-error-will-not-overwrite-just-created = ne va pas écraser le fichier qui vient d'être créé {$target} avec {$source} mv-error-not-replacing = ne remplace pas {$target} mv-error-cannot-move = impossible de déplacer {$source} vers {$target} mv-error-directory-not-empty = Répertoire non vide mv-error-dangling-symlink = impossible de déterminer le type de lien symbolique, car il est suspendu mv-error-no-symlink-support = votre système d'exploitation ne prend pas en charge les liens symboliques mv-error-permission-denied = Permission refusée -mv-error-inter-device-move-failed = échec du déplacement inter-périphérique : '{$from}' vers '{$to}' ; impossible de supprimer la cible : {$err} +mv-error-inter-device-move-failed = échec du déplacement inter-périphérique : {$from} vers {$to} ; impossible de supprimer la cible : {$err} # Messages d'aide mv-help-force = ne pas demander avant d'écraser diff --git a/src/uu/mv/src/hardlink.rs b/src/uu/mv/src/hardlink.rs index 63bb152fd..4c3d77cfe 100644 --- a/src/uu/mv/src/hardlink.rs +++ b/src/uu/mv/src/hardlink.rs @@ -13,6 +13,8 @@ use std::collections::HashMap; use std::io; use std::path::{Path, PathBuf}; +use uucore::display::Quotable; + /// Tracks hardlinks during cross-partition moves to preserve them #[derive(Debug, Default)] pub struct HardlinkTracker { @@ -61,12 +63,12 @@ impl std::fmt::Display for HardlinkError { write!( f, "Failed to preserve hardlink: {} -> {}", - source.display(), - target.display() + source.quote(), + target.quote() ) } Self::Metadata { path, error } => { - write!(f, "Metadata access error for {}: {}", path.display(), error) + write!(f, "Metadata access error for {}: {}", path.quote(), error) } } } @@ -95,13 +97,13 @@ impl From for io::Error { HardlinkError::Scan(msg) => Self::other(msg), HardlinkError::Preservation { source, target } => Self::other(format!( "Failed to preserve hardlink: {} -> {}", - source.display(), - target.display() + source.quote(), + target.quote() )), HardlinkError::Metadata { path, error } => Self::other(format!( "Metadata access error for {}: {}", - path.display(), + path.quote(), error )), } @@ -128,11 +130,7 @@ impl HardlinkTracker { Err(e) => { // Gracefully handle metadata errors by logging and continuing without hardlink tracking if options.verbose { - eprintln!( - "warning: cannot get metadata for {}: {}", - source.display(), - e - ); + eprintln!("warning: cannot get metadata for {}: {}", source.quote(), e); } return Ok(None); } @@ -152,8 +150,8 @@ impl HardlinkTracker { if options.verbose { eprintln!( "preserving hardlink {} -> {} (hardlinked)", - source.display(), - existing_path.display() + source.quote(), + existing_path.quote() ); } return Ok(Some(existing_path.clone())); @@ -189,7 +187,7 @@ impl HardlinkGroupScanner { if let Err(e) = self.scan_single_path(file) { if options.verbose { // Only show warnings for verbose mode - eprintln!("warning: failed to scan {}: {}", file.display(), e); + eprintln!("warning: failed to scan {}: {}", file.quote(), e); } // For non-verbose mode, silently continue for missing files // This provides graceful degradation - we'll lose hardlink info for this file diff --git a/src/uu/mv/src/mv.rs b/src/uu/mv/src/mv.rs index 723875f61..ea80641ba 100644 --- a/src/uu/mv/src/mv.rs +++ b/src/uu/mv/src/mv.rs @@ -648,7 +648,7 @@ fn move_files_into_dir(files: &[PathBuf], target_dir: &Path, options: &Options) // If the target file was already created in this mv call, do not overwrite show!(USimpleError::new( 1, - translate!("mv-error-will-not-overwrite-just-created", "target" => targetpath.display(), "source" => sourcepath.display()), + translate!("mv-error-will-not-overwrite-just-created", "target" => targetpath.quote(), "source" => sourcepath.quote()), )); continue; } @@ -1159,7 +1159,7 @@ fn rename_file_fallback( // Remove existing target file if it exists if to.is_symlink() { fs::remove_file(to).map_err(|err| { - let inter_device_msg = translate!("mv-error-inter-device-move-failed", "from" => from.display(), "to" => to.display(), "err" => err); + let inter_device_msg = translate!("mv-error-inter-device-move-failed", "from" => from.quote(), "to" => to.quote(), "err" => err); io::Error::new(err.kind(), inter_device_msg) })?; } else if to.exists() { diff --git a/src/uu/nl/src/nl.rs b/src/uu/nl/src/nl.rs index 7d1f862aa..39a78fda3 100644 --- a/src/uu/nl/src/nl.rs +++ b/src/uu/nl/src/nl.rs @@ -8,6 +8,7 @@ use std::ffi::{OsStr, OsString}; use std::fs::File; use std::io::{BufRead, BufReader, BufWriter, Read, Write, stdin, stdout}; use std::path::Path; +use uucore::display::Quotable; use uucore::error::{FromIo, UResult, USimpleError, set_exit_code}; use uucore::{format_usage, show_error, translate}; @@ -221,12 +222,11 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { if path.is_dir() { show_error!( "{}", - translate!("nl-error-is-directory", "path" => path.display()) + translate!("nl-error-is-directory", "path" => path.maybe_quote()) ); set_exit_code(1); } else { - let reader = - File::open(path).map_err_context(|| file.to_string_lossy().to_string())?; + let reader = File::open(path).map_err_context(|| file.maybe_quote().to_string())?; let mut buffer = BufReader::new(reader); nl(&mut buffer, &mut stats, &settings)?; } diff --git a/src/uu/printf/locales/en-US.ftl b/src/uu/printf/locales/en-US.ftl index 430fd71fa..7ecea31aa 100644 --- a/src/uu/printf/locales/en-US.ftl +++ b/src/uu/printf/locales/en-US.ftl @@ -249,6 +249,6 @@ printf-after-help = basic anonymous string templating: is set) printf-error-missing-operand = missing operand -printf-warning-ignoring-excess-arguments = ignoring excess arguments, starting with '{ $arg }' +printf-warning-ignoring-excess-arguments = ignoring excess arguments, starting with { $arg } printf-help-version = Print version information printf-help-help = Print help information diff --git a/src/uu/printf/locales/fr-FR.ftl b/src/uu/printf/locales/fr-FR.ftl index 9594c7027..fdedf2497 100644 --- a/src/uu/printf/locales/fr-FR.ftl +++ b/src/uu/printf/locales/fr-FR.ftl @@ -250,6 +250,6 @@ printf-after-help = templating de chaîne anonyme de base : # Messages d'erreur printf-error-missing-operand = opérande manquant -printf-warning-ignoring-excess-arguments = arguments excédentaires ignorés, en commençant par '{ $arg }' +printf-warning-ignoring-excess-arguments = arguments excédentaires ignorés, en commençant par { $arg } printf-help-version = Afficher les informations de version printf-help-help = Afficher cette aide diff --git a/src/uu/printf/src/printf.rs b/src/uu/printf/src/printf.rs index d313c8ace..69be56c91 100644 --- a/src/uu/printf/src/printf.rs +++ b/src/uu/printf/src/printf.rs @@ -6,6 +6,7 @@ use clap::{Arg, ArgAction, Command}; use std::ffi::OsString; use std::io::stdout; use std::ops::ControlFlow; +use uucore::display::Quotable; use uucore::error::{UResult, UUsageError}; use uucore::format::{FormatArgument, FormatArguments, FormatItem, parse_spec_and_escape}; use uucore::translate; @@ -60,7 +61,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { "{}", translate!( "printf-warning-ignoring-excess-arguments", - "arg" => arg_str.to_string_lossy() + "arg" => arg_str.quote() ) ); } diff --git a/src/uu/ptx/src/ptx.rs b/src/uu/ptx/src/ptx.rs index e63d27599..a36521cd7 100644 --- a/src/uu/ptx/src/ptx.rs +++ b/src/uu/ptx/src/ptx.rs @@ -671,7 +671,7 @@ fn write_traditional_output( Box::new(stdout()) } else { let file = File::create(output_filename) - .map_err_context(|| output_filename.to_string_lossy().quote().to_string())?; + .map_err_context(|| output_filename.quote().to_string())?; Box::new(file) }); @@ -809,7 +809,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { if let Some(file) = files.next() { return Err(UUsageError::new( 1, - translate!("ptx-error-extra-operand", "operand" => file.to_string_lossy().quote()), + translate!("ptx-error-extra-operand", "operand" => file.quote()), )); } } diff --git a/src/uu/readlink/src/readlink.rs b/src/uu/readlink/src/readlink.rs index 2c019d6bb..e135e0815 100644 --- a/src/uu/readlink/src/readlink.rs +++ b/src/uu/readlink/src/readlink.rs @@ -10,6 +10,7 @@ use std::ffi::OsString; use std::fs; use std::io::{Write, stdout}; use std::path::{Path, PathBuf}; +use uucore::display::Quotable; use uucore::error::{FromIo, UResult, UUsageError}; use uucore::fs::{MissingHandling, ResolveMode, canonicalize}; use uucore::libc::EINVAL; @@ -93,11 +94,11 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { return Err(1.into()); } - let path = p.to_string_lossy().into_owned(); let message = if err.raw_os_error() == Some(EINVAL) { - translate!("readlink-error-invalid-argument", "path" => path.clone()) + translate!("readlink-error-invalid-argument", "path" => p.maybe_quote()) } else { - err.map_err_context(|| path.clone()).to_string() + err.map_err_context(|| p.maybe_quote().to_string()) + .to_string() }; show_error!("{message}"); return Err(1.into()); diff --git a/src/uu/rm/locales/en-US.ftl b/src/uu/rm/locales/en-US.ftl index a84f746f2..12816693e 100644 --- a/src/uu/rm/locales/en-US.ftl +++ b/src/uu/rm/locales/en-US.ftl @@ -41,7 +41,7 @@ rm-error-cannot-remove-permission-denied = cannot remove {$file}: Permission den rm-error-cannot-remove-is-directory = cannot remove {$file}: Is a directory rm-error-dangerous-recursive-operation = it is dangerous to operate recursively on '/' rm-error-use-no-preserve-root = use --no-preserve-root to override this failsafe -rm-error-refusing-to-remove-directory = refusing to remove '.' or '..' directory: skipping '{$path}' +rm-error-refusing-to-remove-directory = refusing to remove '.' or '..' directory: skipping {$path} rm-error-cannot-remove = cannot remove {$file} # Verbose messages diff --git a/src/uu/rm/locales/fr-FR.ftl b/src/uu/rm/locales/fr-FR.ftl index a3da4ba0b..e1ee8ec23 100644 --- a/src/uu/rm/locales/fr-FR.ftl +++ b/src/uu/rm/locales/fr-FR.ftl @@ -41,7 +41,7 @@ rm-error-cannot-remove-permission-denied = impossible de supprimer {$file} : Per rm-error-cannot-remove-is-directory = impossible de supprimer {$file} : C'est un répertoire rm-error-dangerous-recursive-operation = il est dangereux d'opérer récursivement sur '/' rm-error-use-no-preserve-root = utilisez --no-preserve-root pour outrepasser cette protection -rm-error-refusing-to-remove-directory = refus de supprimer le répertoire '.' ou '..' : ignorer '{$path}' +rm-error-refusing-to-remove-directory = refus de supprimer le répertoire '.' ou '..' : ignorer {$path} rm-error-cannot-remove = impossible de supprimer {$file} # Messages verbeux diff --git a/src/uu/rm/src/rm.rs b/src/uu/rm/src/rm.rs index a20a57d7f..ce1ce47a1 100644 --- a/src/uu/rm/src/rm.rs +++ b/src/uu/rm/src/rm.rs @@ -43,7 +43,7 @@ enum RmError { DangerousRecursiveOperation, #[error("{}", translate!("rm-error-use-no-preserve-root"))] UseNoPreserveRoot, - #[error("{}", translate!("rm-error-refusing-to-remove-directory", "path" => _0.to_string_lossy()))] + #[error("{}", translate!("rm-error-refusing-to-remove-directory", "path" => _0.quote()))] RefusingToRemoveDirectory(OsString), } diff --git a/src/uu/sort/locales/en-US.ftl b/src/uu/sort/locales/en-US.ftl index 21042721a..a5c5d01b6 100644 --- a/src/uu/sort/locales/en-US.ftl +++ b/src/uu/sort/locales/en-US.ftl @@ -17,13 +17,13 @@ sort-cannot-read = cannot read: {$path}: {$error} sort-open-tmp-file-failed = failed to open temporary file: {$error} sort-compress-prog-execution-failed = could not run compress program '{$prog}': {$error} sort-compress-prog-terminated-abnormally = {$prog} terminated abnormally -sort-cannot-create-tmp-file = cannot create temporary file in '{$path}': -sort-file-operands-combined = extra operand '{$file}' +sort-cannot-create-tmp-file = cannot create temporary file in {$path}: +sort-file-operands-combined = extra operand {$file} file operands cannot be combined with --files0-from Try '{$help} --help' for more information. sort-multiple-output-files = multiple output files specified sort-minus-in-stdin = when reading file names from standard input, no file name of '-' allowed -sort-no-input-from = no input from '{$file}' +sort-no-input-from = no input from {$file} sort-invalid-zero-length-filename = {$file}:{$line_num}: invalid zero-length file name sort-options-incompatible = options '-{$opt1}{$opt2}' are incompatible sort-invalid-key = invalid key {$key} diff --git a/src/uu/sort/locales/fr-FR.ftl b/src/uu/sort/locales/fr-FR.ftl index 611613c51..4dbc05a49 100644 --- a/src/uu/sort/locales/fr-FR.ftl +++ b/src/uu/sort/locales/fr-FR.ftl @@ -17,13 +17,13 @@ sort-cannot-read = impossible de lire : {$path} : {$error} sort-open-tmp-file-failed = échec d'ouverture du fichier temporaire : {$error} sort-compress-prog-execution-failed = impossible d'exécuter le programme de compression '{$prog}' : {$error} sort-compress-prog-terminated-abnormally = {$prog} s'est terminé anormalement -sort-cannot-create-tmp-file = impossible de créer un fichier temporaire dans '{$path}' : -sort-file-operands-combined = opérande supplémentaire '{$file}' +sort-cannot-create-tmp-file = impossible de créer un fichier temporaire dans {$path} : +sort-file-operands-combined = opérande supplémentaire {$file} les opérandes de fichier ne peuvent pas être combinées avec --files0-from Essayez '{$help} --help' pour plus d'informations. sort-multiple-output-files = plusieurs fichiers de sortie spécifiés sort-minus-in-stdin = lors de la lecture des noms de fichiers depuis l'entrée standard, aucun nom de fichier '-' n'est autorisé -sort-no-input-from = aucune entrée depuis '{$file}' +sort-no-input-from = aucune entrée depuis {$file} sort-invalid-zero-length-filename = {$file}:{$line_num} : nom de fichier de longueur zéro invalide sort-options-incompatible = les options '-{$opt1}{$opt2}' sont incompatibles sort-invalid-key = clé invalide {$key} diff --git a/src/uu/sort/src/sort.rs b/src/uu/sort/src/sort.rs index ec9ab5b93..f1879f9f7 100644 --- a/src/uu/sort/src/sort.rs +++ b/src/uu/sort/src/sort.rs @@ -158,10 +158,10 @@ pub enum SortError { #[error("{}", translate!("sort-compress-prog-terminated-abnormally", "prog" => .prog.quote()))] CompressProgTerminatedAbnormally { prog: String }, - #[error("{}", translate!("sort-cannot-create-tmp-file", "path" => format!("{}", .path.display())))] + #[error("{}", translate!("sort-cannot-create-tmp-file", "path" => format!("{}", .path.quote())))] TmpFileCreationFailed { path: PathBuf }, - #[error("{}", translate!("sort-file-operands-combined", "file" => format!("{}", .file.display()), "help" => uucore::execution_phrase()))] + #[error("{}", translate!("sort-file-operands-combined", "file" => format!("{}", .file.quote()), "help" => uucore::execution_phrase()))] FileOperandsCombined { file: PathBuf }, #[error("{error}")] @@ -173,10 +173,10 @@ pub enum SortError { #[error("{}", translate!("sort-minus-in-stdin"))] MinusInStdIn, - #[error("{}", translate!("sort-no-input-from", "file" => format!("{}", .file.display())))] + #[error("{}", translate!("sort-no-input-from", "file" => format!("{}", .file.quote())))] EmptyInputFile { file: PathBuf }, - #[error("{}", translate!("sort-invalid-zero-length-filename", "file" => format!("{}", .file.display()), "line_num" => .line_num))] + #[error("{}", translate!("sort-invalid-zero-length-filename", "file" => .file.maybe_quote(), "line_num" => .line_num))] ZeroLengthFileName { file: PathBuf, line_num: usize }, } diff --git a/src/uu/split/src/filenames.rs b/src/uu/split/src/filenames.rs index ce31cbc7c..007f817cc 100644 --- a/src/uu/split/src/filenames.rs +++ b/src/uu/split/src/filenames.rs @@ -89,7 +89,7 @@ pub enum SuffixError { /// Suffix contains a directory separator, which is not allowed. #[error("{}", translate!("split-error-suffix-contains-separator", "value" => .0.quote()))] - ContainsSeparator(String), + ContainsSeparator(OsString), /// Suffix is not large enough to split into specified chunks #[error("{}", translate!("split-error-suffix-too-small", "length" => .0))] @@ -224,9 +224,7 @@ impl Suffix { .unwrap() .clone(); if additional.to_string_lossy().chars().any(is_separator) { - return Err(SuffixError::ContainsSeparator( - additional.to_string_lossy().to_string(), - )); + return Err(SuffixError::ContainsSeparator(additional)); } let result = Self { diff --git a/src/uu/split/src/split.rs b/src/uu/split/src/split.rs index 3fe80cd5d..6f290a7d5 100644 --- a/src/uu/split/src/split.rs +++ b/src/uu/split/src/split.rs @@ -638,7 +638,7 @@ where // STDIN stream that did not fit all content into a buffer // Most likely continuous/infinite input stream Err(io::Error::other( - translate!("split-error-cannot-determine-input-size", "input" => input.to_string_lossy()), + translate!("split-error-cannot-determine-input-size", "input" => input.maybe_quote()), )) } else { // Could be that file size is larger than set read limit @@ -663,7 +663,7 @@ where // TODO It might be possible to do more here // to address all possible file types and edge cases Err(io::Error::other( - translate!("split-error-cannot-determine-file-size", "input" => input.to_string_lossy()), + translate!("split-error-cannot-determine-file-size", "input" => input.maybe_quote()), )) } } @@ -1172,7 +1172,7 @@ where Err(error) => { return Err(USimpleError::new( 1, - translate!("split-error-cannot-read-from-input", "input" => settings.input.to_string_lossy(), "error" => error), + translate!("split-error-cannot-read-from-input", "input" => settings.input.maybe_quote(), "error" => error), )); } } @@ -1534,7 +1534,7 @@ fn split(settings: &Settings) -> UResult<()> { Box::new(stdin()) as Box } else { let r = File::open(Path::new(&settings.input)).map_err_context( - || translate!("split-error-cannot-open-for-reading", "file" => settings.input.to_string_lossy().quote()), + || translate!("split-error-cannot-open-for-reading", "file" => settings.input.quote()), )?; Box::new(r) as Box }; diff --git a/src/uu/sum/src/sum.rs b/src/uu/sum/src/sum.rs index d33961581..70c40b15c 100644 --- a/src/uu/sum/src/sum.rs +++ b/src/uu/sum/src/sum.rs @@ -75,14 +75,14 @@ fn open(name: &OsString) -> UResult> { if path.is_dir() { return Err(USimpleError::new( 2, - translate!("sum-error-is-directory", "name" => name.to_string_lossy().maybe_quote()), + translate!("sum-error-is-directory", "name" => name.maybe_quote()), )); } // Silent the warning as we want to the error message if path.metadata().is_err() { return Err(USimpleError::new( 2, - translate!("sum-error-no-such-file-or-directory", "name" => name.to_string_lossy().maybe_quote()), + translate!("sum-error-no-such-file-or-directory", "name" => name.maybe_quote()), )); } let f = File::open(path).map_err_context(String::new)?; diff --git a/src/uu/tail/locales/en-US.ftl b/src/uu/tail/locales/en-US.ftl index d4b670c49..6f7383aa4 100644 --- a/src/uu/tail/locales/en-US.ftl +++ b/src/uu/tail/locales/en-US.ftl @@ -36,7 +36,7 @@ tail-error-invalid-pid-with-error = invalid PID: { $pid }: { $error } tail-error-invalid-number-out-of-range = invalid number: { $arg }: Numerical result out of range tail-error-invalid-number-overflow = invalid number: { $arg } tail-error-option-used-in-invalid-context = option used in invalid context -- { $option } -tail-error-bad-argument-encoding = bad argument encoding: '{ $arg }' +tail-error-bad-argument-encoding = bad argument encoding: { $arg } tail-error-cannot-watch-parent-directory = cannot watch parent directory of { $path } tail-error-backend-cannot-be-used-too-many-files = { $backend } cannot be used, reverting to polling: Too many open files tail-error-backend-resources-exhausted = { $backend } resources exhausted diff --git a/src/uu/tail/locales/fr-FR.ftl b/src/uu/tail/locales/fr-FR.ftl index 9a12f52eb..85d973571 100644 --- a/src/uu/tail/locales/fr-FR.ftl +++ b/src/uu/tail/locales/fr-FR.ftl @@ -36,7 +36,7 @@ tail-error-invalid-pid-with-error = PID invalide : { $pid } : { $error } tail-error-invalid-number-out-of-range = nombre invalide : { $arg } : Résultat numérique hors limites tail-error-invalid-number-overflow = nombre invalide : { $arg } tail-error-option-used-in-invalid-context = option utilisée dans un contexte invalide -- { $option } -tail-error-bad-argument-encoding = encodage d'argument incorrect : '{ $arg }' +tail-error-bad-argument-encoding = encodage d'argument incorrect : { $arg } tail-error-cannot-watch-parent-directory = impossible de surveiller le répertoire parent de { $path } tail-error-backend-cannot-be-used-too-many-files = { $backend } ne peut pas être utilisé, retour au sondage : Trop de fichiers ouverts tail-error-backend-resources-exhausted = ressources { $backend } épuisées diff --git a/src/uu/tail/src/args.rs b/src/uu/tail/src/args.rs index ef53b3943..4b8807af9 100644 --- a/src/uu/tail/src/args.rs +++ b/src/uu/tail/src/args.rs @@ -362,22 +362,24 @@ pub fn parse_obsolete(arg: &OsString, input: Option<&OsString>) -> UResult Ok(Some(Settings::from_obsolete_args(&args, input))), None => Ok(None), Some(Err(e)) => { - let arg_str = arg.to_string_lossy(); Err(USimpleError::new( 1, match e { parse::ParseError::OutOfRange => { - translate!("tail-error-invalid-number-out-of-range", "arg" => arg_str.quote()) + translate!("tail-error-invalid-number-out-of-range", "arg" => arg.quote()) } parse::ParseError::Overflow => { - translate!("tail-error-invalid-number-overflow", "arg" => arg_str.quote()) + translate!("tail-error-invalid-number-overflow", "arg" => arg.quote()) } // this ensures compatibility to GNU's error message (as tested in misc/tail) parse::ParseError::Context => { - translate!("tail-error-option-used-in-invalid-context", "option" => arg_str.chars().nth(1).unwrap_or_default()) + translate!( + "tail-error-option-used-in-invalid-context", + "option" => arg.to_string_lossy().chars().nth(1).unwrap_or_default(), + ) } parse::ParseError::InvalidEncoding => { - translate!("tail-error-bad-argument-encoding", "arg" => arg_str) + translate!("tail-error-bad-argument-encoding", "arg" => arg.quote()) } }, )) diff --git a/src/uu/tail/src/follow/watch.rs b/src/uu/tail/src/follow/watch.rs index 9b0333efb..1789aa4b9 100644 --- a/src/uu/tail/src/follow/watch.rs +++ b/src/uu/tail/src/follow/watch.rs @@ -58,7 +58,7 @@ impl WatcherRx { } else { return Err(USimpleError::new( 1, - translate!("tail-error-cannot-watch-parent-directory", "path" => path.display()), + translate!("tail-error-cannot-watch-parent-directory", "path" => path.quote()), )); } } diff --git a/src/uu/tee/src/tee.rs b/src/uu/tee/src/tee.rs index fc345a403..20a7c2e8c 100644 --- a/src/uu/tee/src/tee.rs +++ b/src/uu/tee/src/tee.rs @@ -176,7 +176,7 @@ fn tee(options: &Options) -> Result<()> { writers.insert( 0, NamedWriter { - name: translate!("tee-standard-output"), + name: translate!("tee-standard-output").into(), inner: Box::new(stdout()), }, ); @@ -267,10 +267,10 @@ fn open( match mode.write(true).create(true).open(path.as_path()) { Ok(file) => Some(Ok(NamedWriter { inner: Box::new(file), - name: name.to_string_lossy().to_string(), + name: name.clone(), })), Err(f) => { - show_error!("{}: {f}", name.to_string_lossy().maybe_quote()); + show_error!("{}: {f}", name.maybe_quote()); match output_error { Some(OutputErrorMode::Exit | OutputErrorMode::ExitNoPipe) => Some(Err(f)), _ => None, @@ -394,7 +394,7 @@ impl Write for MultiWriter { struct NamedWriter { inner: Box, - pub name: String, + pub name: OsString, } impl Write for NamedWriter { diff --git a/src/uu/touch/src/touch.rs b/src/uu/touch/src/touch.rs index f8fb3c284..79e9609b0 100644 --- a/src/uu/touch/src/touch.rs +++ b/src/uu/touch/src/touch.rs @@ -17,7 +17,7 @@ use clap::{Arg, ArgAction, ArgGroup, ArgMatches, Command}; use filetime::{FileTime, set_file_times, set_symlink_file_times}; use jiff::{Timestamp, Zoned}; use std::borrow::Cow; -use std::ffi::OsString; +use std::ffi::{OsStr, OsString}; use std::fs::{self, File}; use std::io::{Error, ErrorKind}; use std::path::{Path, PathBuf}; @@ -430,9 +430,9 @@ fn touch_file( mtime: FileTime, ) -> UResult<()> { let filename = if is_stdout { - String::from("-") + OsStr::new("-") } else { - path.display().to_string() + path.as_os_str() }; let metadata_result = if opts.no_deref { diff --git a/src/uu/truncate/src/truncate.rs b/src/uu/truncate/src/truncate.rs index 7a607cc1a..8b53d37ef 100644 --- a/src/uu/truncate/src/truncate.rs +++ b/src/uu/truncate/src/truncate.rs @@ -178,7 +178,7 @@ fn file_truncate(filename: &OsString, create: bool, size: u64) -> UResult<()> { if metadata.file_type().is_fifo() { return Err(USimpleError::new( 1, - translate!("truncate-error-cannot-open-no-device", "filename" => filename.to_string_lossy().quote()), + translate!("truncate-error-cannot-open-no-device", "filename" => filename.quote()), )); } } @@ -328,7 +328,7 @@ fn truncate_size_only(size_string: &str, filenames: &[OsString], create: bool) - if m.file_type().is_fifo() { return Err(USimpleError::new( 1, - translate!("truncate-error-cannot-open-no-device", "filename" => filename.to_string_lossy().quote()), + translate!("truncate-error-cannot-open-no-device", "filename" => filename.quote()), )); } m.len() diff --git a/src/uu/tsort/src/tsort.rs b/src/uu/tsort/src/tsort.rs index 4b52e1e45..b985bdf27 100644 --- a/src/uu/tsort/src/tsort.rs +++ b/src/uu/tsort/src/tsort.rs @@ -22,19 +22,19 @@ mod options { #[derive(Debug, Error)] enum TsortError { /// The input file is actually a directory. - #[error("{input}: {message}", input = .0, message = translate!("tsort-error-is-dir"))] - IsDir(String), + #[error("{input}: {message}", input = .0.maybe_quote(), message = translate!("tsort-error-is-dir"))] + IsDir(OsString), /// The number of tokens in the input data is odd. /// /// The list of edges must be even because each edge has two /// components: a source node and a target node. #[error("{input}: {message}", input = .0.maybe_quote(), message = translate!("tsort-error-odd"))] - NumTokensOdd(String), + NumTokensOdd(OsString), /// The graph contains a cycle. - #[error("{input}: {message}", input = .0, message = translate!("tsort-error-loop"))] - Loop(String), + #[error("{input}: {message}", input = .0.maybe_quote(), message = translate!("tsort-error-loop"))] + Loop(OsString), } // Auxiliary struct, just for printing loop nodes via show! macro @@ -59,13 +59,13 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { } else { let path = Path::new(input); if path.is_dir() { - return Err(TsortError::IsDir(input.to_string_lossy().to_string()).into()); + return Err(TsortError::IsDir(input.clone()).into()); } std::fs::read_to_string(path)? }; // Create the directed graph from pairs of tokens in the input data. - let mut g = Graph::new(input.to_string_lossy().to_string()); + let mut g = Graph::new(input.clone()); // Input is considered to be in the format // From1 To1 From2 To2 ... // with tokens separated by whitespaces @@ -80,7 +80,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { break; }; let Some(to) = edge_tokens.next() else { - return Err(TsortError::NumTokensOdd(input.to_string_lossy().to_string()).into()); + return Err(TsortError::NumTokensOdd(input.clone()).into()); }; g.add_edge(from, to); } @@ -130,7 +130,7 @@ impl<'input> Node<'input> { } struct Graph<'input> { - name: String, + name: OsString, nodes: HashMap<&'input str, Node<'input>>, } @@ -141,7 +141,7 @@ enum VisitedState { } impl<'input> Graph<'input> { - fn new(name: String) -> Self { + fn new(name: OsString) -> Self { Self { name, nodes: HashMap::default(), diff --git a/src/uu/unexpand/src/unexpand.rs b/src/uu/unexpand/src/unexpand.rs index 5d1b3319f..b3990ac59 100644 --- a/src/uu/unexpand/src/unexpand.rs +++ b/src/uu/unexpand/src/unexpand.rs @@ -207,12 +207,12 @@ fn open(path: &OsString) -> UResult>> { if filename.is_dir() { Err(Box::new(USimpleError { code: 1, - message: translate!("unexpand-error-is-directory", "path" => filename.display()), + message: translate!("unexpand-error-is-directory", "path" => filename.maybe_quote()), })) } else if path == "-" { Ok(BufReader::new(Box::new(stdin()) as Box)) } else { - file_buf = File::open(path).map_err_context(|| path.to_string_lossy().to_string())?; + file_buf = File::open(path).map_err_context(|| path.maybe_quote().to_string())?; Ok(BufReader::new(Box::new(file_buf) as Box)) } } diff --git a/src/uu/wc/locales/en-US.ftl b/src/uu/wc/locales/en-US.ftl index 410eb3e6e..86e3a63c6 100644 --- a/src/uu/wc/locales/en-US.ftl +++ b/src/uu/wc/locales/en-US.ftl @@ -14,7 +14,7 @@ wc-help-total = when to print a line with total counts; wc-help-words = print the word counts # Error messages -wc-error-files-disabled = extra operand '{ $extra }' +wc-error-files-disabled = extra operand { $extra } file operands cannot be combined with --files0-from wc-error-stdin-repr-not-allowed = when reading file names from standard input, no file name of '-' allowed wc-error-zero-length-filename = invalid zero-length file name diff --git a/src/uu/wc/locales/fr-FR.ftl b/src/uu/wc/locales/fr-FR.ftl index e04d89fd9..1b1ffa7a4 100644 --- a/src/uu/wc/locales/fr-FR.ftl +++ b/src/uu/wc/locales/fr-FR.ftl @@ -14,7 +14,7 @@ wc-help-total = quand afficher une ligne avec les totaux ; wc-help-words = afficher le nombre de mots # Messages d'erreur -wc-error-files-disabled = opérande supplémentaire '{ $extra }' +wc-error-files-disabled = opérande supplémentaire { $extra } les opérandes de fichier ne peuvent pas être combinées avec --files0-from wc-error-stdin-repr-not-allowed = lors de la lecture des noms de fichiers depuis l'entrée standard, aucun nom de fichier '-' autorisé wc-error-zero-length-filename = nom de fichier de longueur nulle invalide diff --git a/src/uu/wc/src/wc.rs b/src/uu/wc/src/wc.rs index 44362e03f..cf2d28e08 100644 --- a/src/uu/wc/src/wc.rs +++ b/src/uu/wc/src/wc.rs @@ -24,7 +24,7 @@ use clap::{Arg, ArgAction, ArgMatches, Command, builder::ValueParser}; use thiserror::Error; use unicode_width::UnicodeWidthChar; use utf8::{BufReadDecoder, BufReadDecoderError}; -use uucore::translate; +use uucore::{display::Quotable, translate}; use uucore::{ error::{FromIo, UError, UResult}, @@ -339,8 +339,8 @@ impl TotalWhen { #[derive(Debug, Error)] enum WcError { - #[error("{}", translate!("wc-error-files-disabled", "extra" => extra))] - FilesDisabled { extra: Cow<'static, str> }, + #[error("{}", translate!("wc-error-files-disabled", "extra" => extra.quote()))] + FilesDisabled { extra: Cow<'static, OsStr> }, #[error("{}", translate!("wc-error-stdin-repr-not-allowed"))] StdinReprNotAllowed, #[error("{}", translate!("wc-error-zero-length-filename"))] @@ -363,7 +363,7 @@ impl WcError { } } fn files_disabled(first_extra: &OsString) -> Self { - let extra = first_extra.to_string_lossy().into_owned().into(); + let extra = first_extra.clone().into(); Self::FilesDisabled { extra } } } diff --git a/src/uucore/locales/en-US.ftl b/src/uucore/locales/en-US.ftl index 09fb45783..4c61b5a3f 100644 --- a/src/uucore/locales/en-US.ftl +++ b/src/uucore/locales/en-US.ftl @@ -47,10 +47,10 @@ selinux-error-context-conversion-failure = failed to set default file creation c # Safe traversal error messages safe-traversal-error-path-contains-null = path contains null byte -safe-traversal-error-open-failed = failed to open '{ $path }': { $source } -safe-traversal-error-stat-failed = failed to stat '{ $path }': { $source } -safe-traversal-error-read-dir-failed = failed to read directory '{ $path }': { $source } -safe-traversal-error-unlink-failed = failed to unlink '{ $path }': { $source } +safe-traversal-error-open-failed = failed to open { $path }: { $source } +safe-traversal-error-stat-failed = failed to stat { $path }: { $source } +safe-traversal-error-read-dir-failed = failed to read directory { $path }: { $source } +safe-traversal-error-unlink-failed = failed to unlink { $path }: { $source } safe-traversal-error-invalid-fd = invalid file descriptor safe-traversal-current-directory = safe-traversal-directory = diff --git a/src/uucore/locales/fr-FR.ftl b/src/uucore/locales/fr-FR.ftl index a8a344688..878907041 100644 --- a/src/uucore/locales/fr-FR.ftl +++ b/src/uucore/locales/fr-FR.ftl @@ -47,10 +47,10 @@ selinux-error-context-conversion-failure = échec de la définition du contexte # Messages d'erreur de traversée sécurisée safe-traversal-error-path-contains-null = le chemin contient un octet null -safe-traversal-error-open-failed = échec de l'ouverture de '{ $path }' : { $source } -safe-traversal-error-stat-failed = échec de l'analyse de '{ $path }' : { $source } -safe-traversal-error-read-dir-failed = échec de la lecture du répertoire '{ $path }' : { $source } -safe-traversal-error-unlink-failed = échec de la suppression de '{ $path }' : { $source } +safe-traversal-error-open-failed = échec de l'ouverture de { $path } : { $source } +safe-traversal-error-stat-failed = échec de l'analyse de { $path } : { $source } +safe-traversal-error-read-dir-failed = échec de la lecture du répertoire { $path } : { $source } +safe-traversal-error-unlink-failed = échec de la suppression de { $path } : { $source } safe-traversal-error-invalid-fd = descripteur de fichier invalide safe-traversal-current-directory = safe-traversal-directory = diff --git a/src/uucore/src/lib/features/backup_control.rs b/src/uucore/src/lib/features/backup_control.rs index c438a7720..ec1ea5002 100644 --- a/src/uucore/src/lib/features/backup_control.rs +++ b/src/uucore/src/lib/features/backup_control.rs @@ -470,8 +470,9 @@ fn existing_backup_path(path: &Path, suffix: &str) -> PathBuf { /// ``` /// pub fn source_is_target_backup(source: &Path, target: &Path, suffix: &str) -> bool { - let source_filename = source.to_string_lossy(); - let target_backup_filename = format!("{}{suffix}", target.to_string_lossy()); + let source_filename = source.as_os_str(); + let mut target_backup_filename = target.as_os_str().to_owned(); + target_backup_filename.push(suffix); source_filename == target_backup_filename } diff --git a/src/uucore/src/lib/features/checksum.rs b/src/uucore/src/lib/features/checksum.rs index 324dba7b3..6e8a17198 100644 --- a/src/uucore/src/lib/features/checksum.rs +++ b/src/uucore/src/lib/features/checksum.rs @@ -817,17 +817,14 @@ fn get_input_file(filename: &OsStr) -> UResult> { match File::open(filename) { Ok(f) => { if f.metadata()?.is_dir() { - Err( - io::Error::other(format!("{}: Is a directory", filename.to_string_lossy())) - .into(), - ) + Err(io::Error::other(format!("{}: Is a directory", filename.maybe_quote())).into()) } else { Ok(Box::new(f)) } } Err(_) => Err(io::Error::other(format!( "{}: No such file or directory", - filename.to_string_lossy() + filename.maybe_quote() )) .into()), } diff --git a/src/uucore/src/lib/features/perms.rs b/src/uucore/src/lib/features/perms.rs index f6a73cc96..2823b35b1 100644 --- a/src/uucore/src/lib/features/perms.rs +++ b/src/uucore/src/lib/features/perms.rs @@ -464,8 +464,8 @@ impl ChownExecutor { *ret = 1; if self.verbosity.level != VerbosityLevel::Silent { show_error!( - "cannot read directory '{}': {}", - dir_path.display(), + "cannot read directory {}: {}", + dir_path.quote(), strip_errno(&e) ); } @@ -484,11 +484,7 @@ impl ChownExecutor { Err(e) => { *ret = 1; if self.verbosity.level != VerbosityLevel::Silent { - show_error!( - "cannot access '{}': {}", - entry_path.display(), - strip_errno(&e) - ); + show_error!("cannot access {}: {}", entry_path.quote(), strip_errno(&e)); } continue; } @@ -549,8 +545,8 @@ impl ChownExecutor { *ret = 1; if self.verbosity.level != VerbosityLevel::Silent { show_error!( - "cannot access '{}': {}", - entry_path.display(), + "cannot access {}: {}", + entry_path.quote(), strip_errno(&e) ); } @@ -582,8 +578,8 @@ impl ChownExecutor { ret = 1; if let Some(path) = e.path() { show_error!( - "cannot access '{}': {}", - path.display(), + "cannot access {}: {}", + path.quote(), if let Some(error) = e.io_error() { strip_errno(error) } else { @@ -702,7 +698,7 @@ impl ChownExecutor { DirFd::open(path) .map_err(|e| { if self.verbosity.level != VerbosityLevel::Silent { - show_error!("cannot access '{}': {}", path.display(), strip_errno(&e)); + show_error!("cannot access {}: {}", path.quote(), strip_errno(&e)); } }) .ok() diff --git a/src/uucore/src/lib/features/safe_traversal.rs b/src/uucore/src/lib/features/safe_traversal.rs index a405ea5d9..6574910a9 100644 --- a/src/uucore/src/lib/features/safe_traversal.rs +++ b/src/uucore/src/lib/features/safe_traversal.rs @@ -18,13 +18,14 @@ use std::ffi::{CString, OsStr, OsString}; use std::io; use std::os::unix::ffi::OsStrExt; use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, OwnedFd, RawFd}; -use std::path::Path; +use std::path::{Path, PathBuf}; use nix::dir::Dir; use nix::fcntl::{OFlag, openat}; use nix::libc; use nix::sys::stat::{FchmodatFlags, FileStat, Mode, fchmodat, fstatat}; use nix::unistd::{Gid, Uid, UnlinkatFlags, fchown, fchownat, unlinkat}; +use os_display::Quotable; use crate::translate; @@ -34,30 +35,30 @@ pub enum SafeTraversalError { #[error("{}", translate!("safe-traversal-error-path-contains-null"))] PathContainsNull, - #[error("{}", translate!("safe-traversal-error-open-failed", "path" => path, "source" => source))] + #[error("{}", translate!("safe-traversal-error-open-failed", "path" => path.quote(), "source" => source))] OpenFailed { - path: String, + path: PathBuf, #[source] source: io::Error, }, - #[error("{}", translate!("safe-traversal-error-stat-failed", "path" => path, "source" => source))] + #[error("{}", translate!("safe-traversal-error-stat-failed", "path" => path.quote(), "source" => source))] StatFailed { - path: String, + path: PathBuf, #[source] source: io::Error, }, - #[error("{}", translate!("safe-traversal-error-read-dir-failed", "path" => path, "source" => source))] + #[error("{}", translate!("safe-traversal-error-read-dir-failed", "path" => path.quote(), "source" => source))] ReadDirFailed { - path: String, + path: PathBuf, #[source] source: io::Error, }, - #[error("{}", translate!("safe-traversal-error-unlink-failed", "path" => path, "source" => source))] + #[error("{}", translate!("safe-traversal-error-unlink-failed", "path" => path.quote(), "source" => source))] UnlinkFailed { - path: String, + path: PathBuf, #[source] source: io::Error, }, @@ -112,7 +113,7 @@ impl DirFd { let flags = OFlag::O_RDONLY | OFlag::O_DIRECTORY | OFlag::O_CLOEXEC; let fd = nix::fcntl::open(path, flags, Mode::empty()).map_err(|e| { SafeTraversalError::OpenFailed { - path: path.to_string_lossy().into_owned(), + path: path.into(), source: io::Error::from_raw_os_error(e as i32), } })?; @@ -128,7 +129,7 @@ impl DirFd { let flags = OFlag::O_RDONLY | OFlag::O_DIRECTORY | OFlag::O_CLOEXEC; let fd = openat(&self.fd, name_cstr.as_c_str(), flags, Mode::empty()).map_err(|e| { SafeTraversalError::OpenFailed { - path: name.to_string_lossy().into_owned(), + path: name.into(), source: io::Error::from_raw_os_error(e as i32), } })?; @@ -149,7 +150,7 @@ impl DirFd { let stat = fstatat(&self.fd, name_cstr.as_c_str(), flags).map_err(|e| { SafeTraversalError::StatFailed { - path: name.to_string_lossy().into_owned(), + path: name.into(), source: io::Error::from_raw_os_error(e as i32), } })?; @@ -170,7 +171,7 @@ impl DirFd { /// Get raw stat data for this directory pub fn fstat(&self) -> io::Result { let stat = nix::sys::stat::fstat(&self.fd).map_err(|e| SafeTraversalError::StatFailed { - path: translate!("safe-traversal-current-directory"), + path: translate!("safe-traversal-current-directory").into(), source: io::Error::from_raw_os_error(e as i32), })?; @@ -181,7 +182,7 @@ impl DirFd { pub fn read_dir(&self) -> io::Result> { read_dir_entries(&self.fd).map_err(|e| { SafeTraversalError::ReadDirFailed { - path: translate!("safe-traversal-directory"), + path: translate!("safe-traversal-directory").into(), source: e, } .into() @@ -200,7 +201,7 @@ impl DirFd { unlinkat(&self.fd, name_cstr.as_c_str(), flags).map_err(|e| { SafeTraversalError::UnlinkFailed { - path: name.to_string_lossy().into_owned(), + path: name.into(), source: io::Error::from_raw_os_error(e as i32), } })?; diff --git a/src/uucore/src/lib/mods/locale.rs b/src/uucore/src/lib/mods/locale.rs index 559dc72ef..ed8955525 100644 --- a/src/uucore/src/lib/mods/locale.rs +++ b/src/uucore/src/lib/mods/locale.rs @@ -14,6 +14,7 @@ use std::path::{Path, PathBuf}; use std::str::FromStr; use std::sync::OnceLock; +use os_display::Quotable; use thiserror::Error; use unic_langid::LanguageIdentifier; @@ -458,8 +459,8 @@ fn get_locales_dir(p: &str) -> Result { Err(LocalizationError::LocalesDirNotFound(format!( "Development locales directory not found at {} or {}", - dev_path.display(), - fallback_dev_path.display() + dev_path.quote(), + fallback_dev_path.quote() ))) } @@ -481,7 +482,7 @@ fn get_locales_dir(p: &str) -> Result { Err(LocalizationError::LocalesDirNotFound(format!( "Release locales directory not found starting from {}", - exe_dir.display() + exe_dir.quote() ))) } } @@ -576,7 +577,7 @@ mod tests { Err(LocalizationError::LocalesDirNotFound(format!( "No localization strings found for {locale} in {}", - test_locales_dir.display() + test_locales_dir.quote() ))) } diff --git a/tests/by-util/test_chmod.rs b/tests/by-util/test_chmod.rs index 1378aab00..328a043af 100644 --- a/tests/by-util/test_chmod.rs +++ b/tests/by-util/test_chmod.rs @@ -371,7 +371,7 @@ fn test_permission_denied() { .arg("o=r") .arg("d") .fails() - .stderr_is("chmod: 'd/no-x/y': Permission denied\n"); + .stderr_is("chmod: d/no-x/y: Permission denied\n"); } #[test] @@ -394,7 +394,7 @@ fn test_chmod_recursive() { #[cfg(not(target_os = "linux"))] let err_msg = "chmod: Permission denied\n"; #[cfg(target_os = "linux")] - let err_msg = "chmod: 'z': Permission denied\n"; + let err_msg = "chmod: z: Permission denied\n"; // only the permissions of folder `a` and `z` are changed // folder can't be read after read permission is removed diff --git a/tests/by-util/test_tail.rs b/tests/by-util/test_tail.rs index 3f6455c21..75a7a65be 100644 --- a/tests/by-util/test_tail.rs +++ b/tests/by-util/test_tail.rs @@ -4800,7 +4800,7 @@ fn test_obsolete_encoding_unix() { .arg(invalid_utf8_arg) .fails_with_code(1) .no_stdout() - .stderr_is("tail: bad argument encoding: '-�b'\n"); + .stderr_is("tail: bad argument encoding: $'-\\x80'$'b'\n"); } #[test] @@ -4817,7 +4817,7 @@ fn test_obsolete_encoding_windows() { .arg(&invalid_utf16_arg) .fails_with_code(1) .no_stdout() - .stderr_is("tail: bad argument encoding: '-�b'\n"); + .stderr_is("tail: bad argument encoding: \"-`u{D800}b\"\n"); } #[test]