From ee462a585a597d22caf855b73ee1b5438385be13 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Fri, 12 Sep 2025 16:58:05 +0200 Subject: [PATCH] safe traversal: add support for translations --- src/uucore/locales/en-US.ftl | 10 ++++++++ src/uucore/locales/fr-FR.ftl | 10 ++++++++ src/uucore/src/lib/features/safe_traversal.rs | 25 +++++++++++-------- 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/src/uucore/locales/en-US.ftl b/src/uucore/locales/en-US.ftl index 5e0816b02..7ff7a3a87 100644 --- a/src/uucore/locales/en-US.ftl +++ b/src/uucore/locales/en-US.ftl @@ -37,3 +37,13 @@ action-removing = removing action-creating = creating action-reading = reading action-writing = writing + +# 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-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 0734f56ba..aff6a9071 100644 --- a/src/uucore/locales/fr-FR.ftl +++ b/src/uucore/locales/fr-FR.ftl @@ -37,3 +37,13 @@ action-removing = suppression action-creating = création action-reading = lecture action-writing = écriture + +# 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-invalid-fd = descripteur de fichier invalide +safe-traversal-current-directory = +safe-traversal-directory = diff --git a/src/uucore/src/lib/features/safe_traversal.rs b/src/uucore/src/lib/features/safe_traversal.rs index 2fe3df400..09e527824 100644 --- a/src/uucore/src/lib/features/safe_traversal.rs +++ b/src/uucore/src/lib/features/safe_traversal.rs @@ -27,34 +27,36 @@ use nix::fcntl::{OFlag, openat}; use nix::sys::stat::{FileStat, Mode, fstatat}; use nix::unistd::{UnlinkatFlags, unlinkat}; +use crate::translate; + // Custom error types for better error reporting #[derive(thiserror::Error, Debug)] pub enum SafeTraversalError { - #[error("path contains null byte")] + #[error("{}", translate!("safe-traversal-error-path-contains-null"))] PathContainsNull, - #[error("failed to open '{path}': {source}")] + #[error("{}", translate!("safe-traversal-error-open-failed", "path" => path, "source" => source))] OpenFailed { path: String, #[source] source: io::Error, }, - #[error("failed to stat '{path}': {source}")] + #[error("{}", translate!("safe-traversal-error-stat-failed", "path" => path, "source" => source))] StatFailed { path: String, #[source] source: io::Error, }, - #[error("failed to read directory '{path}': {source}")] + #[error("{}", translate!("safe-traversal-error-read-dir-failed", "path" => path, "source" => source))] ReadDirFailed { path: String, #[source] source: io::Error, }, - #[error("failed to unlink '{path}': {source}")] + #[error("{}", translate!("safe-traversal-error-unlink-failed", "path" => path, "source" => source))] UnlinkFailed { path: String, #[source] @@ -65,9 +67,10 @@ pub enum SafeTraversalError { impl From for io::Error { fn from(err: SafeTraversalError) -> Self { match err { - SafeTraversalError::PathContainsNull => { - io::Error::new(io::ErrorKind::InvalidInput, "path contains null byte") - } + SafeTraversalError::PathContainsNull => io::Error::new( + io::ErrorKind::InvalidInput, + translate!("safe-traversal-error-path-contains-null"), + ), SafeTraversalError::OpenFailed { source, .. } => source, SafeTraversalError::StatFailed { source, .. } => source, SafeTraversalError::ReadDirFailed { source, .. } => source, @@ -168,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: "".to_string(), + path: translate!("safe-traversal-current-directory"), source: io::Error::from_raw_os_error(e as i32), })?; @@ -179,7 +182,7 @@ impl DirFd { pub fn read_dir(&self) -> io::Result> { read_dir_entries(&self.fd).map_err(|e| { SafeTraversalError::ReadDirFailed { - path: "".to_string(), + path: translate!("safe-traversal-directory"), source: e, } .into() @@ -211,7 +214,7 @@ impl DirFd { if fd < 0 { return Err(io::Error::new( io::ErrorKind::InvalidInput, - "invalid file descriptor", + translate!("safe-traversal-error-invalid-fd"), )); } // SAFETY: We've verified fd >= 0, and the caller is transferring ownership