mirror of
https://github.com/uutils/coreutils.git
synced 2026-06-10 15:48:22 -07:00
realpath: fix handling of non-UTF-8 filenames
This commit is contained in:
@@ -5,8 +5,9 @@
|
||||
|
||||
// spell-checker:ignore (ToDO) retcode
|
||||
|
||||
use clap::{Arg, ArgAction, ArgMatches, Command, builder::NonEmptyStringValueParser};
|
||||
use clap::{Arg, ArgAction, ArgMatches, Command};
|
||||
use std::{
|
||||
ffi::OsString,
|
||||
io::{Write, stdout},
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
@@ -40,7 +41,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||
/* the list of files */
|
||||
|
||||
let paths: Vec<PathBuf> = matches
|
||||
.get_many::<String>(ARG_FILES)
|
||||
.get_many::<OsString>(ARG_FILES)
|
||||
.unwrap()
|
||||
.map(PathBuf::from)
|
||||
.collect();
|
||||
@@ -145,21 +146,21 @@ pub fn uu_app() -> Command {
|
||||
Arg::new(OPT_RELATIVE_TO)
|
||||
.long(OPT_RELATIVE_TO)
|
||||
.value_name("DIR")
|
||||
.value_parser(NonEmptyStringValueParser::new())
|
||||
.value_parser(clap::value_parser!(OsString))
|
||||
.help(translate!("realpath-help-relative-to")),
|
||||
)
|
||||
.arg(
|
||||
Arg::new(OPT_RELATIVE_BASE)
|
||||
.long(OPT_RELATIVE_BASE)
|
||||
.value_name("DIR")
|
||||
.value_parser(NonEmptyStringValueParser::new())
|
||||
.value_parser(clap::value_parser!(OsString))
|
||||
.help(translate!("realpath-help-relative-base")),
|
||||
)
|
||||
.arg(
|
||||
Arg::new(ARG_FILES)
|
||||
.action(ArgAction::Append)
|
||||
.required(true)
|
||||
.value_parser(NonEmptyStringValueParser::new())
|
||||
.value_parser(clap::value_parser!(OsString))
|
||||
.value_hint(clap::ValueHint::AnyPath),
|
||||
)
|
||||
}
|
||||
@@ -174,10 +175,10 @@ fn prepare_relative_options(
|
||||
resolve_mode: ResolveMode,
|
||||
) -> UResult<(Option<PathBuf>, Option<PathBuf>)> {
|
||||
let relative_to = matches
|
||||
.get_one::<String>(OPT_RELATIVE_TO)
|
||||
.get_one::<OsString>(OPT_RELATIVE_TO)
|
||||
.map(PathBuf::from);
|
||||
let relative_base = matches
|
||||
.get_one::<String>(OPT_RELATIVE_BASE)
|
||||
.get_one::<OsString>(OPT_RELATIVE_BASE)
|
||||
.map(PathBuf::from);
|
||||
let relative_to = canonicalize_relative_option(relative_to, can_mode, resolve_mode)?;
|
||||
let relative_base = canonicalize_relative_option(relative_base, can_mode, resolve_mode)?;
|
||||
|
||||
@@ -464,3 +464,28 @@ fn test_realpath_trailing_slash() {
|
||||
fn test_realpath_empty() {
|
||||
new_ucmd!().fails_with_code(1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(target_os = "linux")]
|
||||
fn test_realpath_non_utf8_paths() {
|
||||
use std::ffi::OsStr;
|
||||
use std::os::unix::ffi::OsStrExt;
|
||||
|
||||
let scene = TestScenario::new(util_name!());
|
||||
let at = &scene.fixtures;
|
||||
|
||||
// Create a test file with non-UTF-8 bytes in the name
|
||||
let non_utf8_bytes = b"test_\xFF\xFE.txt";
|
||||
let non_utf8_name = OsStr::from_bytes(non_utf8_bytes);
|
||||
|
||||
// Create the actual file
|
||||
at.touch(non_utf8_name);
|
||||
|
||||
// Test that realpath handles non-UTF-8 paths without crashing
|
||||
let result = scene.ucmd().arg(non_utf8_name).succeeds();
|
||||
|
||||
// The result should contain the non-UTF-8 bytes
|
||||
let output = result.stdout_str_lossy();
|
||||
assert!(output.contains("test_"));
|
||||
assert!(output.contains(".txt"));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user