fix: Un-escape message footer marks in full messages (get_html) (#8427)

Un-escapes footer marks in long plain-text messages when retrieved with
`get_message_html`/`dc_get_msg_html`.

Additionally, makes escaping stricter,
only matching lines starting with `-- ` instead of `--`.

Fixes: #8269

Signed-off-by: Jagoda Ślązak <jslazak@jslazak.com>
This commit is contained in:
Jagoda Estera Ślązak
2026-07-20 09:44:14 +02:00
committed by GitHub
parent aadd11a771
commit 0c40b52ec8
3 changed files with 70 additions and 17 deletions
+22 -2
View File
@@ -21,6 +21,7 @@ use crate::message::{Message, MsgId};
use crate::mimeparser::parse_message_id;
use crate::param::{Param::SendHtml, Params};
use crate::plaintext::PlainText;
use crate::simplify::unescape_message_footer_marks;
use crate::sql;
use crate::tools::{buf_compress, buf_decompress};
@@ -174,14 +175,14 @@ impl HtmlMsgParser {
if self.html.is_empty()
&& let Ok(decoded_data) = mail.get_body()
{
self.html = decoded_data;
self.html = unescape_message_footer_marks(&decoded_data);
}
} else if mimetype == mime::TEXT_PLAIN
&& self.plain.is_none()
&& let Ok(decoded_data) = mail.get_body()
{
self.plain = Some(PlainText {
text: decoded_data,
text: unescape_message_footer_marks(&decoded_data),
flowed: if let Some(format) = mail.ctype.params.get("format") {
format.as_str().eq_ignore_ascii_case("flowed")
} else {
@@ -417,6 +418,25 @@ test some special html-characters as &lt; &gt; and &amp; but also &quot; and &#x
);
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_htmlparse_plain_escaped_footer() {
let t = TestContext::new().await;
let raw = include_bytes!("../test-data/message/text_plain_escaped_footer.eml");
let (parser, _) = HtmlMsgParser::from_bytes(&t.ctx, raw).unwrap();
assert_eq!(
parser.html,
r#"<!DOCTYPE html>
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="color-scheme" content="light dark" />
</head><body dir="auto" style="unicode-bidi: plaintext">
-- escaped footer 1<br/>
-- escaped footer 2<br/>
</body></html>
"#
);
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_htmlparse_html() {
let t = TestContext::new().await;