Handle invalid UTF-8, fixes #34

This commit is contained in:
sharkdp 2017-06-11 15:28:18 +02:00 committed by David Peter
parent 087e709acd
commit 24070b0be0
2 changed files with 21 additions and 13 deletions

View File

@ -8,11 +8,12 @@ extern crate ignore;
pub mod lscolors; pub mod lscolors;
pub mod fshelper; pub mod fshelper;
use std::borrow::Cow;
use std::env; use std::env;
use std::error::Error; use std::error::Error;
use std::ffi::OsStr;
use std::fs; use std::fs;
use std::io::Write; use std::io::Write;
use std::ops::Deref;
#[cfg(target_family = "unix")] #[cfg(target_family = "unix")]
use std::os::unix::fs::PermissionsExt; use std::os::unix::fs::PermissionsExt;
use std::path::{Path, Component}; use std::path::{Path, Component};
@ -70,14 +71,14 @@ struct FdOptions {
/// Root directory /// Root directory
static ROOT_DIR : &'static str = "/"; static ROOT_DIR : &'static str = "/";
/// Parent directory
static PARENT_DIR : &'static str = "..";
/// Print a search result to the console. /// Print a search result to the console.
fn print_entry(base: &Path, entry: &Path, config: &FdOptions) { fn print_entry(base: &Path, entry: &Path, config: &FdOptions) {
let path_full = base.join(entry); let path_full = base.join(entry);
let path_str = match entry.to_str() { let path_str = entry.to_string_lossy();
Some(p) => p,
None => return
};
#[cfg(target_family = "unix")] #[cfg(target_family = "unix")]
let is_executable = |p: &std::path::PathBuf| { let is_executable = |p: &std::path::PathBuf| {
@ -102,12 +103,12 @@ fn print_entry(base: &Path, entry: &Path, config: &FdOptions) {
// Traverse the path and colorize each component // Traverse the path and colorize each component
for component in entry.components() { for component in entry.components() {
let comp_str = match component { let comp_str = match component {
Component::Normal(p) => p.to_str().unwrap(), Component::Normal(p) => p.to_string_lossy(),
Component::ParentDir => "..", Component::ParentDir => Cow::from(PARENT_DIR),
_ => error("Unexpected path component") _ => error("Unexpected path component")
}; };
component_path.push(Path::new(comp_str)); component_path.push(Path::new(comp_str.deref()));
let style = let style =
if component_path.symlink_metadata() if component_path.symlink_metadata()
@ -181,18 +182,20 @@ fn scan(root: &Path, pattern: &Regex, base: &Path, config: &FdOptions) {
}; };
let path_rel = path_rel_buf.as_path(); let path_rel = path_rel_buf.as_path();
let search_str = let search_str_o =
if config.search_full_path { if config.search_full_path {
path_rel.to_str() Some(path_rel.to_string_lossy())
} else { } else {
path_rel.file_name() path_rel.file_name()
.and_then(OsStr::to_str) .map(|f| f.to_string_lossy())
}; };
search_str.and_then(|s| pattern.find(s)) if let Some(search_str) = search_str_o {
pattern.find(&*search_str)
.map(|_| print_entry(base, path_rel, config)); .map(|_| print_entry(base, path_rel, config));
} }
} }
}
/// Print error message to stderr and exit with status `1`. /// Print error message to stderr and exit with status `1`.
fn error(message: &str) -> ! { fn error(message: &str) -> ! {

View File

@ -198,5 +198,10 @@ $root/one/two/C.Foo
$root/one/two/three/d.foo $root/one/two/three/d.foo
$root/one/two/three/directory_foo" --absolute-path foo $root/one/two/three/directory_foo" --absolute-path foo
suite "Invalid UTF-8"
touch "$(printf 'test-invalid-utf8-\xc3.txt')"
expect "$(printf 'test-invalid-utf8-\ufffd.txt')" test-invalid-utf8
# All done # All done
echo echo