diff --git a/src/uu/pathchk/src/pathchk.rs b/src/uu/pathchk/src/pathchk.rs index c46ed39ae..e73ac2d7c 100644 --- a/src/uu/pathchk/src/pathchk.rs +++ b/src/uu/pathchk/src/pathchk.rs @@ -6,6 +6,7 @@ // spell-checker:ignore (ToDO) lstat use clap::{Arg, ArgAction, Command}; +use std::ffi::OsString; use std::fs; use std::io::{ErrorKind, Write}; use uucore::LocalizedCommand; @@ -53,7 +54,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { }; // take necessary actions - let paths = matches.get_many::(options::PATH); + let paths = matches.get_many::(options::PATH); if paths.is_none() { return Err(UUsageError::new( 1, @@ -65,8 +66,9 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { // FIXME: TCS, seems inefficient and overly verbose (?) let mut res = true; for p in paths.unwrap() { + let path_str = p.to_string_lossy(); let mut path = Vec::new(); - for path_segment in p.split('/') { + for path_segment in path_str.split('/') { path.push(path_segment.to_string()); } res &= check_path(&mode, &path); @@ -108,7 +110,8 @@ pub fn uu_app() -> Command { Arg::new(options::PATH) .hide(true) .action(ArgAction::Append) - .value_hint(clap::ValueHint::AnyPath), + .value_hint(clap::ValueHint::AnyPath) + .value_parser(clap::value_parser!(OsString)), ) } diff --git a/tests/by-util/test_pathchk.rs b/tests/by-util/test_pathchk.rs index 064f0aa27..d0197d9bf 100644 --- a/tests/by-util/test_pathchk.rs +++ b/tests/by-util/test_pathchk.rs @@ -2,6 +2,8 @@ // // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. +#[cfg(target_os = "linux")] +use std::os::unix::ffi::OsStringExt; use uutests::new_ucmd; #[test] @@ -164,3 +166,17 @@ fn test_posix_all() { // fail on empty path new_ucmd!().args(&["-p", "-P", ""]).fails().no_stdout(); } + +#[test] +#[cfg(target_os = "linux")] +fn test_pathchk_non_utf8_paths() { + use uutests::at_and_ucmd; + + let (at, mut ucmd) = at_and_ucmd!(); + let filename = std::ffi::OsString::from_vec(vec![0xFF, 0xFE]); + + // Create the file so pathchk can check it exists + std::fs::write(at.plus(&filename), b"test").unwrap(); + + ucmd.arg(&filename).succeeds(); +}