summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrabite <rabite@posteo.de>2020-02-08 00:17:56 +0100
committerrabite <rabite@posteo.de>2020-02-08 00:17:56 +0100
commite3b4c997bf3f0075c6e1ecb282117d9cade3a440 (patch)
treed001ff84ecb5a134ce0d982ad38813164ea02aa1
parent6afca62010f2b6e7dc4921c4d4aa02ce5e5c3b33 (diff)
fix crash by catching tree_magic's panic and handle it gracefully
-rw-r--r--src/fail.rs4
-rw-r--r--src/files.rs53
-rw-r--r--src/preview.rs5
-rw-r--r--src/quick_actions.rs10
-rw-r--r--src/trait_ext.rs2
5 files changed, 56 insertions, 18 deletions
diff --git a/src/fail.rs b/src/fail.rs
index 1abdea7..36a88d4 100644
--- a/src/fail.rs
+++ b/src/fail.rs
@@ -382,7 +382,9 @@ pub enum MimeError {
#[fail(display = "File access failed! Error: {}", _0)]
AccessFailed(Box<HError>),
#[fail(display = "No MIME type found for this file",)]
- NoMimeFound
+ NoMimeFound,
+ #[fail(display = "Paniced while trying to find MIME type for: {}!", _0)]
+ Panic(String),
}
impl From<MimeError> for HError {
diff --git a/src/files.rs b/src/files.rs
index 914f16f..d9f4534 100644
--- a/src/files.rs
+++ b/src/files.rs
@@ -961,23 +961,52 @@ impl File {
Ok((size as u32, unit))
}
- pub fn get_mime(&self) -> Option<mime_guess::Mime> {
+ // Sadly tree_magic tends to panic (in unwraps a None) when called
+ // with things like pipes, non-existing files. and other stuff. To
+ // prevent it from crashing hunter it's necessary to catch the
+ // panic with a custom panic hook and handle it gracefully by just
+ // doing nothing
+ pub fn get_mime(&self) -> HResult<mime_guess::Mime> {
+ use std::panic;
+ use crate::fail::MimeError;
+
if let Some(ext) = self.path.extension() {
let mime = mime_guess::from_ext(&ext.to_string_lossy()).first();
- mime
- } else {
- // Fix crash in tree_magic when called on non-regular file
- // Also fix crash when a file doesn't exist any more
- self.meta()
- .and_then(|meta| {
- if meta.is_file() && self.path.exists() {
- let mime = tree_magic::from_filepath(&self.path);
- mime::Mime::from_str(&mime).ok()
- } else { None }
- })
+ if mime.is_some() {
+ return Ok(mime.unwrap());
+ }
}
+
+ self.meta()
+ .map(|meta| {
+ // Take and replace panic handler which does nothing
+ let panic_hook = panic::take_hook();
+ panic::set_hook(Box::new(|_| {} ));
+
+ // Catch possible panic caused by tree_magic
+ let mime = panic::catch_unwind(|| {
+ match meta.is_file() && self.path.exists() {
+ true => {
+ let mime = tree_magic::from_filepath(&self.path);
+ mime::Mime::from_str(&mime).ok()
+ }
+ false => None
+ }
+ });
+
+ // Restore previous panic handler
+ panic::set_hook(panic_hook);
+
+ mime
+ }).unwrap_or(Ok(None))
+ .unwrap_or(None)
+ .ok_or_else(|| {
+ let file = self.name.clone();
+ HError::Mime(MimeError::Panic(file))
+ })
}
+
pub fn is_text(&self) -> bool {
tree_magic::match_filepath("text/plain", &self.path)
}
diff --git a/src/preview.rs b/src/preview.rs
index 0b27176..7e4439a 100644
--- a/src/preview.rs
+++ b/src/preview.rs
@@ -381,7 +381,10 @@ impl Previewer {
return Ok(preview?);
}
- if let Some(mime) = file.get_mime() {
+ if let Some(mime) = file.get_mime()
+ .log_and()
+ .ok()
+ {
let mime_type = mime.type_().as_str();
let is_gif = mime.subtype() == "gif";
let has_media = core.config().media_available();
diff --git a/src/quick_actions.rs b/src/quick_actions.rs
index 8f7fa24..5a08e0e 100644
--- a/src/quick_actions.rs
+++ b/src/quick_actions.rs
@@ -12,7 +12,7 @@ use std::ffi::OsString;
use std::str::FromStr;
-use crate::fail::{HResult, HError, KeyBindError};
+use crate::fail::{HResult, HError, KeyBindError, ErrorLog};
use crate::widget::{Widget, WidgetCore, Events};
use crate::foldview::{Foldable, FoldableWidgetExt, ActingExt};
use crate::listview::ListView;
@@ -432,12 +432,16 @@ impl QuickFiles for Vec<File> {
fn common_mime(&self) -> Option<Mime> {
let first_mime = self
.get(0)?
- .get_mime();
+ .get_mime()
+ .log_and()
+ .ok();
self.iter()
.fold(first_mime, |common_mime, file| {
- let cur_mime = file.get_mime();
+ let cur_mime = file.get_mime()
+ .log_and()
+ .ok();
if &cur_mime == &common_mime {
cur_mime
diff --git a/src/trait_ext.rs b/src/trait_ext.rs
index 90ce6d3..530d1e8 100644
--- a/src/trait_ext.rs
+++ b/src/trait_ext.rs
@@ -43,6 +43,6 @@ impl PathBufMime for PathBuf {
.map(|mime| {
Ok(format!("{}", mime))
})
- .ok_or(MimeError::NoMimeFound)?
+ .map_err(|_| MimeError::NoMimeFound)?
}
}