diff --git a/cli/src/commands/mod.rs b/cli/src/commands/mod.rs index e54ded3fd..8cbc360b2 100644 --- a/cli/src/commands/mod.rs +++ b/cli/src/commands/mod.rs @@ -16,6 +16,7 @@ pub use fix::*; pub use fmt::*; pub use scan::*; +use std::borrow::Cow; use std::fs; use std::io::stdout; use std::path::PathBuf; @@ -211,10 +212,10 @@ impl Component for CompileState { } } -fn truncate_with_ellipsis(s: String, max_length: usize) -> String { +fn truncate_with_ellipsis(s: Cow, max_length: usize) -> Cow { if s.len() <= max_length { s } else { - format!("{}...", &s[..max_length - 3]) + format!("{}...", &s[..max_length - 3]).into() } } diff --git a/cli/src/commands/scan.rs b/cli/src/commands/scan.rs index 3eb654e43..0be3eef65 100644 --- a/cli/src/commands/scan.rs +++ b/cli/src/commands/scan.rs @@ -1,3 +1,4 @@ +use std::borrow::Cow; use std::cmp::min; use std::fs::File; use std::path::{Path, PathBuf}; @@ -526,6 +527,25 @@ impl ScanState { } } +// superconsole will not print any string that contains Unicode characters that +// are spaces but are not the ASCII space character, so we replace them all. +// See https://github.com/VirusTotal/yara-x/pull/163 for discussion. +fn replace_whitespace(path: &Path) -> Cow { + let mut s = path.to_string_lossy(); + if s.chars().any(|c| c != ' ' && c.is_whitespace()) { + let mut r = String::with_capacity(s.len()); + for c in s.chars() { + if c.is_whitespace() { + r.push(' ') + } else { + r.push(c) + } + } + s = Cow::Owned(r); + } + s +} + impl Component for ScanState { fn draw_unchecked( &self, @@ -566,7 +586,7 @@ impl Component for ScanState { for (file, start_time) in self.files_in_progress.lock().unwrap().iter() { - let path = file.display().to_string(); + let path = replace_whitespace(file); // The length of the elapsed is 7 characters. let spaces = " " .repeat(dimensions.width.saturating_sub(path.len() + 7));