mirror of
https://github.com/uutils/coreutils.git
synced 2026-06-10 15:48:22 -07:00
Fix expand to handle non-UTF-8 filenames
This commit is contained in:
@@ -170,7 +170,7 @@ fn tabstops_parse(s: &str) -> Result<(RemainingMode, Vec<usize>), ParseError> {
|
||||
}
|
||||
|
||||
struct Options {
|
||||
files: Vec<String>,
|
||||
files: Vec<OsString>,
|
||||
tabstops: Vec<usize>,
|
||||
tspaces: String,
|
||||
iflag: bool,
|
||||
@@ -204,9 +204,9 @@ impl Options {
|
||||
.unwrap(); // length of tabstops is guaranteed >= 1
|
||||
let tspaces = " ".repeat(nspaces);
|
||||
|
||||
let files: Vec<String> = match matches.get_many::<String>(options::FILES) {
|
||||
Some(s) => s.map(|v| v.to_string()).collect(),
|
||||
None => vec!["-".to_owned()],
|
||||
let files: Vec<OsString> = match matches.get_many::<OsString>(options::FILES) {
|
||||
Some(s) => s.cloned().collect(),
|
||||
None => vec![OsString::from("-")],
|
||||
};
|
||||
|
||||
Ok(Self {
|
||||
@@ -283,16 +283,18 @@ pub fn uu_app() -> Command {
|
||||
Arg::new(options::FILES)
|
||||
.action(ArgAction::Append)
|
||||
.hide(true)
|
||||
.value_hint(clap::ValueHint::FilePath),
|
||||
.value_hint(clap::ValueHint::FilePath)
|
||||
.value_parser(clap::value_parser!(OsString)),
|
||||
)
|
||||
}
|
||||
|
||||
fn open(path: &str) -> UResult<BufReader<Box<dyn Read + 'static>>> {
|
||||
fn open(path: &OsString) -> UResult<BufReader<Box<dyn Read + 'static>>> {
|
||||
let file_buf;
|
||||
if path == "-" {
|
||||
Ok(BufReader::new(Box::new(stdin()) as Box<dyn Read>))
|
||||
} else {
|
||||
file_buf = File::open(path).map_err_context(|| path.to_string())?;
|
||||
let path_ref = Path::new(path);
|
||||
file_buf = File::open(path_ref).map_err_context(|| path.to_string_lossy().to_string())?;
|
||||
Ok(BufReader::new(Box::new(file_buf) as Box<dyn Read>))
|
||||
}
|
||||
}
|
||||
@@ -446,7 +448,7 @@ fn expand(options: &Options) -> UResult<()> {
|
||||
if Path::new(file).is_dir() {
|
||||
show_error!(
|
||||
"{}",
|
||||
translate!("expand-error-is-directory", "file" => file)
|
||||
translate!("expand-error-is-directory", "file" => file.to_string_lossy())
|
||||
);
|
||||
set_exit_code(1);
|
||||
continue;
|
||||
|
||||
@@ -426,3 +426,19 @@ fn test_nonexisting_file() {
|
||||
.stderr_contains("expand: nonexistent: No such file or directory")
|
||||
.stdout_contains_line("// !note: file contains significant whitespace");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(target_os = "linux")]
|
||||
fn test_expand_non_utf8_paths() {
|
||||
use std::os::unix::ffi::OsStringExt;
|
||||
use uutests::at_and_ucmd;
|
||||
|
||||
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\tworld\ntest\tline\n").unwrap();
|
||||
|
||||
ucmd.arg(&filename)
|
||||
.succeeds()
|
||||
.stdout_is("hello world\ntest line\n");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user