From bfdd6f36e213a271ec09afc8624921f1be68d4d5 Mon Sep 17 00:00:00 2001 From: "B. Petersen" Date: Mon, 27 Apr 2020 12:24:12 +0200 Subject: [PATCH] regard line with ony '--' as footer mark partly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit the footer mark normally used in email-conversations is `-- `, note the trailing space, see RFC 3676, §4.3 unfortunately, the final space is removed by some providers, which lead to footers showing up on delta-to-delta-conversations (on nondc-to-delta, this is not an issue as we cannot be sure anyway and show a [...] therefore) this change accepts lines with only `--` as a footer separator if there is no other footer separator and if the line before is empty and the line after is not. as there is still some chance to remove text accidentally, see tests, some protection against that is needed in another commit. --- src/simplify.rs | 43 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/src/simplify.rs b/src/simplify.rs index cf61dc8ae..985639cf1 100644 --- a/src/simplify.rs +++ b/src/simplify.rs @@ -1,13 +1,25 @@ /// Remove standard (RFC 3676, §4.3) footer if it is found. fn remove_message_footer<'a>(lines: &'a [&str]) -> &'a [&'a str] { + let mut nearly_standard_footer = None; for (ix, &line) in lines.iter().enumerate() { - // quoted-printable may encode `-- ` to `-- =20` which is converted - // back to `-- ` match line { + // some providers encode `-- ` to `-- =20` which results in `-- ` "-- " | "-- " => return &lines[..ix], + // some providers encode `-- ` to `=2D-` which results in only `--`; + // use that only when no other footer is found + // and if the line before is empty and the line after is not empty + "--" => { + if (ix == 0 || lines[ix - 1] == "") && ix != lines.len() - 1 && lines[ix + 1] != "" + { + nearly_standard_footer = Some(ix); + } + } _ => (), } } + if let Some(ix) = nearly_standard_footer { + return &lines[..ix]; + } lines } @@ -268,4 +280,31 @@ mod tests { assert_eq!(lines, &["not a quote", "> first", "> second"]); assert!(!has_top_quote); } + + #[test] + fn test_remove_message_footer() { + let input = "text\n--\nno footer".to_string(); + let (plain, _) = simplify(input, true); + assert_eq!(plain, "text\n--\nno footer"); + + let input = "text\n\n--\n\nno footer".to_string(); + let (plain, _) = simplify(input, true); + assert_eq!(plain, "text\n\n--\n\nno footer"); + + let input = "text\n\n-- no footer\n\n".to_string(); + let (plain, _) = simplify(input, true); + assert_eq!(plain, "text\n\n-- no footer"); + + let input = "text\n\n--\nno footer\n-- \nfooter".to_string(); + let (plain, _) = simplify(input, true); + assert_eq!(plain, "text\n\n--\nno footer"); + + let input = "text\n\n--\ntreated as footer when unescaped".to_string(); + let (plain, _) = simplify(input, true); + assert_eq!(plain, "text"); // see remove_message_footer() for some explanations + + let input = "--\ntreated as footer when unescaped".to_string(); + let (plain, _) = simplify(input, true); + assert_eq!(plain, ""); + } }