From 596784e70eb6932a1873d5154a09038cbc09189a Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Fri, 8 Aug 2025 21:12:54 +0200 Subject: [PATCH] Fix base64/base32/basenc to handle non-UTF-8 filenames --- src/uu/base32/src/base_common.rs | 6 ++++-- tests/by-util/test_base64.rs | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/uu/base32/src/base_common.rs b/src/uu/base32/src/base_common.rs index db1e97016..5c5dd983d 100644 --- a/src/uu/base32/src/base_common.rs +++ b/src/uu/base32/src/base_common.rs @@ -6,6 +6,7 @@ // spell-checker:ignore hexupper lsbf msbf unpadded nopad aGVsbG8sIHdvcmxkIQ use clap::{Arg, ArgAction, Command}; +use std::ffi::OsString; use std::fs::File; use std::io::{self, ErrorKind, Read, Seek, SeekFrom}; use std::path::{Path, PathBuf}; @@ -44,14 +45,14 @@ pub mod options { impl Config { pub fn from(options: &clap::ArgMatches) -> UResult { - let to_read = match options.get_many::(options::FILE) { + let to_read = match options.get_many::(options::FILE) { Some(mut values) => { let name = values.next().unwrap(); if let Some(extra_op) = values.next() { return Err(UUsageError::new( BASE_CMD_PARSE_ERROR, - translate!("base-common-extra-operand", "operand" => extra_op.quote()), + translate!("base-common-extra-operand", "operand" => extra_op.to_string_lossy().quote()), )); } @@ -143,6 +144,7 @@ pub fn base_app(about: &'static str, usage: &str) -> Command { Arg::new(options::FILE) .index(1) .action(ArgAction::Append) + .value_parser(clap::value_parser!(OsString)) .value_hint(clap::ValueHint::FilePath), ) } diff --git a/tests/by-util/test_base64.rs b/tests/by-util/test_base64.rs index ad0d1c2b1..17b46ab29 100644 --- a/tests/by-util/test_base64.rs +++ b/tests/by-util/test_base64.rs @@ -2,9 +2,25 @@ // // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. +#[cfg(target_os = "linux")] +use uutests::at_and_ucmd; use uutests::new_ucmd; use uutests::util::TestScenario; +#[test] +#[cfg(target_os = "linux")] +fn test_base64_non_utf8_paths() { + use std::os::unix::ffi::OsStringExt; + let (at, mut ucmd) = at_and_ucmd!(); + + let filename = std::ffi::OsString::from_vec(vec![0xFF, 0xFE]); + std::fs::write(at.plus(&filename), b"hello world").unwrap(); + + ucmd.arg(&filename) + .succeeds() + .stdout_is("aGVsbG8gd29ybGQ=\n"); +} + #[test] fn test_encode() { let input = "hello, world!";