events: Fix markdown content detection
Encoded HTML entities would be detected as a change. Use the parsed events instead to check if markdown syntax was detected.
This commit is contained in:
parent
7ab6e3ed02
commit
a710229d9d
@ -238,12 +238,9 @@ impl Text {
|
|||||||
/// Returns `None` if no Markdown formatting was found.
|
/// Returns `None` if no Markdown formatting was found.
|
||||||
#[cfg(feature = "markdown")]
|
#[cfg(feature = "markdown")]
|
||||||
pub fn markdown(body: impl AsRef<str>) -> Option<Self> {
|
pub fn markdown(body: impl AsRef<str>) -> Option<Self> {
|
||||||
let body = body.as_ref();
|
use super::room::message::parse_markdown;
|
||||||
let mut html_body = String::new();
|
|
||||||
|
|
||||||
pulldown_cmark::html::push_html(&mut html_body, pulldown_cmark::Parser::new(body));
|
parse_markdown(body.as_ref()).map(Self::html)
|
||||||
|
|
||||||
(html_body != format!("<p>{}</p>\n", body)).then(|| Self::html(html_body))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_mimetype() -> String {
|
fn default_mimetype() -> String {
|
||||||
|
@ -592,12 +592,7 @@ impl FormattedBody {
|
|||||||
/// Returns `None` if no Markdown formatting was found.
|
/// Returns `None` if no Markdown formatting was found.
|
||||||
#[cfg(feature = "markdown")]
|
#[cfg(feature = "markdown")]
|
||||||
pub fn markdown(body: impl AsRef<str>) -> Option<Self> {
|
pub fn markdown(body: impl AsRef<str>) -> Option<Self> {
|
||||||
let body = body.as_ref();
|
parse_markdown(body.as_ref()).map(Self::html)
|
||||||
let mut html_body = String::new();
|
|
||||||
|
|
||||||
pulldown_cmark::html::push_html(&mut html_body, pulldown_cmark::Parser::new(body));
|
|
||||||
|
|
||||||
(html_body != format!("<p>{}</p>\n", body)).then(|| Self::html(html_body))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sanitize this `FormattedBody` if its format is `MessageFormat::Html`.
|
/// Sanitize this `FormattedBody` if its format is `MessageFormat::Html`.
|
||||||
@ -636,3 +631,43 @@ pub struct CustomEventContent {
|
|||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
data: JsonObject,
|
data: JsonObject,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "markdown")]
|
||||||
|
pub(crate) fn parse_markdown(text: &str) -> Option<String> {
|
||||||
|
use pulldown_cmark::{Event, Parser, Tag};
|
||||||
|
|
||||||
|
let mut found_first_paragraph = false;
|
||||||
|
|
||||||
|
let has_markdown = Parser::new(text).any(|ref event| {
|
||||||
|
let is_text = matches!(event, Event::Text(_));
|
||||||
|
let is_break = matches!(event, Event::SoftBreak | Event::HardBreak);
|
||||||
|
let is_first_paragraph_start = if matches!(event,
|
||||||
|
Event::Start(tag)
|
||||||
|
if matches!(tag, Tag::Paragraph)
|
||||||
|
) {
|
||||||
|
if found_first_paragraph {
|
||||||
|
false
|
||||||
|
} else {
|
||||||
|
found_first_paragraph = true;
|
||||||
|
true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
};
|
||||||
|
let is_paragraph_end = matches!(event,
|
||||||
|
Event::End(tag)
|
||||||
|
if matches!(tag, Tag::Paragraph)
|
||||||
|
);
|
||||||
|
|
||||||
|
!is_text && !is_break && !is_first_paragraph_start && !is_paragraph_end
|
||||||
|
});
|
||||||
|
|
||||||
|
if !has_markdown {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut html_body = String::new();
|
||||||
|
pulldown_cmark::html::push_html(&mut html_body, Parser::new(text));
|
||||||
|
|
||||||
|
Some(html_body)
|
||||||
|
}
|
||||||
|
@ -302,6 +302,28 @@ fn markdown_content_serialization() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(feature = "markdown")]
|
||||||
|
fn markdown_detection() {
|
||||||
|
use ruma_common::events::room::message::FormattedBody;
|
||||||
|
|
||||||
|
// No markdown
|
||||||
|
let formatted_body = FormattedBody::markdown("A simple message.");
|
||||||
|
assert_matches!(formatted_body, None);
|
||||||
|
|
||||||
|
// Multiple paragraphs trigger markdown
|
||||||
|
let formatted_body = FormattedBody::markdown("A message\nwith\n\nmultiple\n\nparagraphs");
|
||||||
|
formatted_body.unwrap();
|
||||||
|
|
||||||
|
// HTML entities don't trigger markdown.
|
||||||
|
let formatted_body = FormattedBody::markdown("A message with & HTML < entities");
|
||||||
|
assert_matches!(formatted_body, None);
|
||||||
|
|
||||||
|
// HTML triggers markdown.
|
||||||
|
let formatted_body = FormattedBody::markdown("<span>An HTML message</span>");
|
||||||
|
formatted_body.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn verification_request_deserialization() {
|
fn verification_request_deserialization() {
|
||||||
let user_id = user_id!("@example2:localhost");
|
let user_id = user_id!("@example2:localhost");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user