diff options
author | Dan Davison <dandavison7@gmail.com> | 2021-10-26 09:46:45 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-10-26 09:46:45 -0400 |
commit | ec372683a190427c0fc7b31646849da10996a940 (patch) | |
tree | 84e6cb7407ff73fe7b4a071f7807c8e49e76c7c7 | |
parent | a975f3dd82437d7f6aa1b754525caa849ff00206 (diff) |
Revert git blame handling (#746)
* Security bug:
time-rs/time#293
https://rustsec.org/advisories/RUSTSEC-2020-0159.html
https://github.com/dandavison/delta/runs/4003260368?check_suite_focus=true
* No fix available in the chrono crate:
https://github.com/chronotope/chrono/issues/602
-rw-r--r-- | src/delta.rs | 2 | ||||
-rw-r--r-- | src/handlers/blame.rs | 183 | ||||
-rw-r--r-- | src/handlers/mod.rs | 1 | ||||
-rw-r--r-- | src/paint.rs | 2 |
4 files changed, 0 insertions, 188 deletions
diff --git a/src/delta.rs b/src/delta.rs index 92d8691f..cab9d6fb 100644 --- a/src/delta.rs +++ b/src/delta.rs @@ -22,7 +22,6 @@ pub enum State { HunkPlus(Option<String>), // In hunk; added line (raw_line) SubmoduleLog, // In a submodule section, with gitconfig diff.submodule = log SubmoduleShort(String), // In a submodule section, with gitconfig diff.submodule = short - Blame(String), // In a line of `git blame` output. Unknown, // The following elements are created when a line is wrapped to display it: HunkZeroWrapped, // Wrapped unchanged line @@ -120,7 +119,6 @@ impl<'a> StateMachine<'a> { || self.handle_submodule_log_line()? || self.handle_submodule_short_line()? || self.handle_hunk_line()? - || self.handle_blame_line()? || self.should_skip_line() || self.emit_line_unchanged()?; } diff --git a/src/handlers/blame.rs b/src/handlers/blame.rs deleted file mode 100644 index 5cbeaa2c..00000000 --- a/src/handlers/blame.rs +++ /dev/null @@ -1,183 +0,0 @@ -use chrono::{DateTime, FixedOffset}; -use lazy_static::lazy_static; -use regex::Regex; - -use crate::color; -use crate::config; -use crate::delta::{self, State, StateMachine}; -use crate::format::{self, Placeholder}; -use crate::paint::BgShouldFill; -use crate::style::Style; - -impl<'a> StateMachine<'a> { - /// If this is a line of git blame output then render it accordingly. If - /// this is the first blame line, then set the syntax-highlighter language - /// according to delta.default-language. - pub fn handle_blame_line(&mut self) -> std::io::Result<bool> { - let mut handled_line = false; - self.painter.emit()?; - if matches!(self.state, State::Unknown | State::Blame(_)) { - if let Some(blame) = - parse_git_blame_line(&self.line, &self.config.blame_timestamp_format) - { - // Determine color for this line - let color = if let Some(color) = self.blame_commit_colors.get(blame.commit) { - color - } else { - let n_commits = self.blame_commit_colors.len(); - let n_colors = self.config.blame_palette.len(); - let new_color = &self.config.blame_palette[(n_commits + 1) % n_colors]; - self.blame_commit_colors - .insert(blame.commit.to_owned(), new_color.to_owned()); - new_color - }; - let mut style = Style::from_colors(None, color::parse_color(color, true)); - style.is_syntax_highlighted = true; - - // Construct commit metadata, paint, and emit - let format_data = format::parse_line_number_format( - &self.config.blame_format, - &*BLAME_PLACEHOLDER_REGEX, - false, - ); - write!( - self.painter.writer, - "{}", - style.paint(format_blame_metadata(&format_data, &blame, self.config)) - )?; - - // Emit syntax-highlighted code - if matches!(self.state, State::Unknown) { - if let Some(lang) = self.config.default_language.as_ref() { - self.painter.set_syntax(Some(lang)); - self.painter.set_highlighter(); - } - self.state = State::Blame(blame.commit.to_owned()); - } - self.painter.syntax_highlight_and_paint_line( - blame.code, - style, - self.state.clone(), - BgShouldFill::default(), - ); - handled_line = true - } - } - Ok(handled_line) - } -} - -#[derive(Debug)] -pub struct BlameLine<'a> { - pub commit: &'a str, - pub author: &'a str, - pub time: DateTime<FixedOffset>, - pub line_number: usize, - pub code: &'a str, -} - -// E.g. -//ea82f2d0 (Dan Davison 2021-08-22 18:20:19 -0700 120) let mut handled_line = self.handle_commit_meta_header_line()? - -lazy_static! { - static ref BLAME_LINE_REGEX: Regex = Regex::new( - r"(?x) -^ -( - [0-9a-f]{8} # commit hash -) -[\ ] -\( # open ( -( - [^\ ].*[^\ ] # author name -) -[\ ]+ -( # timestamp - [0-9]{4}-[0-9]{2}-[0-9]{2}\ [0-9]{2}:[0-9]{2}:[0-9]{2}\ [-+][0-9]{4} -) -[\ ]+ -( - [0-9]+ # line number -) -\) # close ) -( - .* # code, with leading space -) -$ -" - ) - .unwrap(); -} - -pub fn parse_git_blame_line<'a>(line: &'a str, timestamp_format: &str) -> Option<BlameLine<'a>> { - let caps = BLAME_LINE_REGEX.captures(line)?; - - let commit = caps.get(1).unwrap().as_str(); - let author = caps.get(2).unwrap().as_str(); - let timestamp = caps.get(3).unwrap().as_str(); - - let time = DateTime::parse_from_str(timestamp, timestamp_format).ok()?; - - let line_number = caps.get(4).unwrap().as_str().parse::<usize>().ok()?; - - let code = caps.get(5).unwrap().as_str(); - - Some(BlameLine { - commit, - author, - time, - line_number, - code, - }) -} - -lazy_static! { - pub static ref BLAME_PLACEHOLDER_REGEX: Regex = - format::make_placeholder_regex(&["timestamp", "author", "commit"]); -} - -pub fn format_blame_metadata( - format_data: &[format::FormatStringPlaceholderData], - blame: &BlameLine, - config: &config::Config, -) -> String { - let mut s = String::new(); - let mut suffix = ""; - for placeholder in format_data { - s.push_str(placeholder.prefix.as_str()); - - let alignment_spec = placeholder - .alignment_spec - .as_ref() - .unwrap_or(&format::Align::Left); - let width = placeholder.width.unwrap_or(15); - - let pad = |s| format::pad(s, width, alignment_spec); - match placeholder.placeholder { - Some(Placeholder::Str("timestamp")) => s.push_str(&pad( - &chrono_humanize::HumanTime::from(blame.time).to_string(), - )), - Some(Placeholder::Str("author")) => s.push_str(&pad(blame.author)), - Some(Placeholder::Str("commit")) => { - s.push_str(&pad(&delta::format_raw_line(blame.commit, config))) - } - None => {} - _ => unreachable!("Unexpected `git blame` input"), - } - suffix = placeholder.suffix.as_str(); - } - s.push_str(suffix); - s -} - -#[test] -fn test_blame_line_regex() { - for line in &[ - "ea82f2d0 (Dan Davison 2021-08-22 18:20:19 -0700 120) let mut handled_line = self.handle_commit_meta_header_line()?", - "b2257cfa (Dan Davison 2020-07-18 15:34:43 -0400 1) use std::borrow::Cow;" - ] { - let caps = BLAME_LINE_REGEX.captures(line); - assert!(caps.is_some()); - assert!(parse_git_blame_line(line, "%Y-%m-%d %H:%M:%S %z").is_some()); - } -} diff --git a/src/handlers/mod.rs b/src/handlers/mod.rs index db27e28f..6302c739 100644 --- a/src/handlers/mod.rs +++ b/src/handlers/mod.rs @@ -1,6 +1,5 @@ /// This module contains functions handling input lines encountered during the /// main `StateMachine::consume()` loop. -pub mod blame; pub mod commit_meta; pub mod diff_stat; pub mod draw; diff --git a/src/paint.rs b/src/paint.rs index 3dd4ae4a..bcf3e941 100644 --- a/src/paint.rs +++ b/src/paint.rs @@ -468,7 +468,6 @@ impl<'a> Painter<'a> { (config.plus_style, config.plus_non_emph_style) } } - State::Blame(_) => (diff_sections[0].0, diff_sections[0].0), _ => (config.null_style, config.null_style), }; let fill_style = if style_sections_contain_more_than_one_style(diff_sections) { @@ -622,7 +621,6 @@ impl<'a> Painter<'a> { } State::HunkHeader(_, _) => true, State::HunkMinus(Some(_)) | State::HunkPlus(Some(_)) => false, - State::Blame(_) => true, _ => panic!( "should_compute_syntax_highlighting is undefined for state {:?}", state |