diff --git a/src/uu/shred/src/shred.rs b/src/uu/shred/src/shred.rs index 5d550a98edf..6d6d68fbc54 100644 --- a/src/uu/shred/src/shred.rs +++ b/src/uu/shred/src/shred.rs @@ -21,8 +21,8 @@ use uucore::display::Quotable; use uucore::error::{FromIo, UResult, USimpleError, UUsageError, strip_errno}; use uucore::parser::parse_size::parse_size_u64; use uucore::parser::shortcut_value_parser::ShortcutValueParser; -use uucore::translate; use uucore::{format_usage, show_error, show_if_err}; +use uucore::{translate, translate_text}; pub mod options { pub const FORCE: &str = "force"; @@ -630,13 +630,13 @@ fn wipe_file( if path.is_dir() { return Err(USimpleError::new( 1, - translate!("shred-failed-to-open-for-writing-is-a-directory", "file" => path.maybe_quote()), + translate_text!("shred-failed-to-open-for-writing-is-a-directory", "file" => path.maybe_quote()), )); } if fs::metadata(path).is_err_and(|e| e.kind() == io::ErrorKind::NotADirectory) { return Err(USimpleError::new( 1, - translate!("shred-failed-to-open-for-writing-not-a-directory", "file" => path.maybe_quote()), + translate_text!("shred-failed-to-open-for-writing-not-a-directory", "file" => path.maybe_quote()), )); } } @@ -651,13 +651,13 @@ fn wipe_file( Ok(md) if !md.is_file() => { return Err(USimpleError::new( 1, - translate!("shred-not-a-file", "file" => path.maybe_quote()), + translate_text!("shred-not-a-file", "file" => path.maybe_quote()), )); } Err(err) if err.kind() == io::ErrorKind::NotFound => { return Err(USimpleError::new( 1, - translate!("shred-no-such-file-or-directory", "file" => path.maybe_quote()), + translate_text!("shred-no-such-file-or-directory", "file" => path.maybe_quote()), )); } _ => {} @@ -717,7 +717,7 @@ fn wipe_file( .truncate(false) .open(path) .map_err_context( - || translate!("shred-failed-to-open-for-writing", "file" => path.maybe_quote()), + || translate_text!("shred-failed-to-open-for-writing", "file" => path.maybe_quote()), )?; let size = match size { @@ -728,7 +728,7 @@ fn wipe_file( for (i, pass_type) in pass_sequence.into_iter().enumerate() { if verbose { let pass_name = pass_name(&pass_type); - let msg = translate!("shred-pass-progress", "file" => path.maybe_quote()); + let msg = translate_text!("shred-pass-progress", "file" => path.maybe_quote()); show_error!( "{msg} {}/{total_passes} ({pass_name})...", (i + 1).to_string() @@ -736,13 +736,13 @@ fn wipe_file( } // size is an optional argument for exactly how many bytes we want to shred do_pass(&mut file, &pass_type, exact, random_source, size).map_err_context( - || translate!("shred-file-write-pass-failed", "file" => path.maybe_quote()), + || translate_text!("shred-file-write-pass-failed", "file" => path.maybe_quote()), )?; } if remove_method != RemoveMethod::None { do_remove(path, verbose, remove_method).map_err_context( - || translate!("shred-failed-to-remove-file", "file" => path.maybe_quote()), + || translate_text!("shred-failed-to-remove-file", "file" => path.maybe_quote()), )?; } Ok(()) @@ -834,7 +834,7 @@ fn wipe_name(orig_path: &Path, verbose: bool, remove_method: RemoveMethod) -> Pa break; } Err(e) => { - let msg = translate!("shred-couldnt-rename", "file" => last_path.maybe_quote(), "new_name" => new_path.quote(), "error" => strip_errno(&e)); + let msg = translate_text!("shred-couldnt-rename", "file" => last_path.maybe_quote(), "new_name" => new_path.quote(), "error" => strip_errno(&e)); show_error!("{msg}"); // TODO: replace with our error management std::process::exit(1); @@ -850,7 +850,7 @@ fn do_remove(path: &Path, verbose: bool, remove_method: RemoveMethod) -> Result< if verbose { show_error!( "{}", - translate!("shred-removing", "file" => path.maybe_quote()) + translate_text!("shred-removing", "file" => path.maybe_quote()) ); } @@ -865,7 +865,7 @@ fn do_remove(path: &Path, verbose: bool, remove_method: RemoveMethod) -> Result< if verbose { show_error!( "{}", - translate!("shred-removed", "file" => path.maybe_quote()) + translate_text!("shred-removed", "file" => path.maybe_quote()) ); } diff --git a/tests/by-util/test_shred.rs b/tests/by-util/test_shred.rs index 09cea46b439..527fd457364 100644 --- a/tests/by-util/test_shred.rs +++ b/tests/by-util/test_shred.rs @@ -585,3 +585,30 @@ fn test_couldnt_rename() { .fails_with_code(1) .stderr_is("shred: /proc/self/mem: Couldn't rename to '/proc/self/000': No such file or directory\n"); } + +#[rstest::rstest] +#[case(&["1e3"], "shred: 1e3: No such file or directory\n")] +#[case(&["007"], "shred: 007: Not a file\n")] +#[cfg(not(windows))] +fn test_numeric_looking_file_names_are_kept_verbatim( + #[case] args: &[&str], + #[case] expected: &str, +) { + // File names such as "007" or "1e3" must not be reformatted as numbers + // in error messages. + let (at, mut ucmd) = at_and_ucmd!(); + at.mkdir("007"); + ucmd.args(args).fails_with_code(1).stderr_is(expected); +} + +#[test] +#[cfg(not(windows))] +fn test_numeric_looking_file_name_verbose_remove() { + let (at, mut ucmd) = at_and_ucmd!(); + at.touch("2.50"); + ucmd.args(&["-v", "-u", "-n", "0", "2.50"]) + .succeeds() + .stderr_contains("shred: 2.50: removing\n") + .stderr_contains("shred: 2.50: removed\n"); + assert!(!at.file_exists("2.50")); +}