Fix more to handle non-UTF-8 filenames

This commit is contained in:
Sylvestre Ledru
2025-08-14 10:52:24 +02:00
parent 0706675830
commit b54d999cc6
2 changed files with 34 additions and 7 deletions
+10 -7
View File
@@ -4,6 +4,7 @@
// file that was distributed with this source code.
use std::{
ffi::OsString,
fs::File,
io::{BufRead, BufReader, Stdin, Stdout, Write, stdin, stdout},
panic::set_hook,
@@ -154,12 +155,12 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
}));
let matches = uu_app().get_matches_from_localized(args);
let mut options = Options::from(&matches);
if let Some(files) = matches.get_many::<String>(options::FILES) {
if let Some(files) = matches.get_many::<OsString>(options::FILES) {
let length = files.len();
let mut files_iter = files.map(|s| s.as_str()).peekable();
while let (Some(file), next_file) = (files_iter.next(), files_iter.peek()) {
let file = Path::new(file);
let mut files_iter = files.peekable();
while let (Some(file_os), next_file) = (files_iter.next(), files_iter.peek()) {
let file = Path::new(file_os);
if file.is_dir() {
show!(UUsageError::new(
0,
@@ -188,11 +189,12 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
}
Ok(opened_file) => opened_file,
};
let next_file_str = next_file.map(|f| f.to_string_lossy().into_owned());
more(
InputType::File(BufReader::new(opened_file)),
length > 1,
file.to_str(),
next_file.copied(),
Some(&file.to_string_lossy()),
next_file_str.as_deref(),
&mut options,
)?;
}
@@ -311,7 +313,8 @@ pub fn uu_app() -> Command {
.required(false)
.action(ArgAction::Append)
.help(translate!("more-help-files"))
.value_hint(clap::ValueHint::FilePath),
.value_hint(clap::ValueHint::FilePath)
.value_parser(clap::value_parser!(OsString)),
)
}
+24
View File
@@ -126,3 +126,27 @@ fn test_invalid_file_perms() {
.stderr_contains("permission denied");
}
}
#[test]
#[cfg(target_os = "linux")]
fn test_more_non_utf8_paths() {
use std::fs;
if std::io::stdout().is_terminal() {
let (at, mut ucmd) = at_and_ucmd!();
// Create test file with normal name first
at.write("temp.txt", "test content for non-UTF-8 file");
// Rename to non-UTF-8 name
#[cfg(unix)]
{
use std::os::unix::ffi::OsStrExt;
let file_name = std::ffi::OsStr::from_bytes(b"test_\xFF\xFE.txt");
fs::rename(at.subdir.join("temp.txt"), at.subdir.join(file_name)).unwrap();
// Test that more can handle non-UTF-8 filenames without crashing
ucmd.arg(file_name).succeeds();
}
}
}