mirror of
https://github.com/AtHeartEngineer/lemmy.git
synced 2026-01-09 05:18:04 -05:00
* Special characters in markdown links (ref #5380) * fix (fixes #5380) * fix test
This commit is contained in:
@@ -1,6 +1,15 @@
|
||||
use super::{link_rule::Link, MARKDOWN_PARSER};
|
||||
use crate::settings::SETTINGS;
|
||||
use markdown_it::{plugins::cmark::inline::image::Image, NodeValue};
|
||||
use super::link_rule::Link;
|
||||
use crate::{settings::SETTINGS, utils::markdown::link_rule};
|
||||
use markdown_it::{
|
||||
parser::linkfmt::LinkFormatter,
|
||||
plugins::cmark::{
|
||||
block::fence,
|
||||
inline::{image, image::Image},
|
||||
},
|
||||
MarkdownIt,
|
||||
NodeValue,
|
||||
};
|
||||
use std::sync::LazyLock;
|
||||
use url::Url;
|
||||
use urlencoding::encode;
|
||||
|
||||
@@ -55,7 +64,18 @@ pub fn markdown_find_links(src: &str) -> Vec<(usize, usize)> {
|
||||
|
||||
// Walk the syntax tree to find positions of image or link urls
|
||||
fn find_urls<T: NodeValue + UrlAndTitle>(src: &str) -> Vec<(usize, usize)> {
|
||||
let ast = MARKDOWN_PARSER.parse(src);
|
||||
// Use separate markdown parser here, with most features disabled for faster parsing,
|
||||
// and a dummy link formatter which doesnt normalize links.
|
||||
static PARSER: LazyLock<MarkdownIt> = LazyLock::new(|| {
|
||||
let mut p = MarkdownIt::new();
|
||||
p.link_formatter = Box::new(NoopLinkFormatter {});
|
||||
image::add(&mut p);
|
||||
fence::add(&mut p);
|
||||
link_rule::add(&mut p);
|
||||
p
|
||||
});
|
||||
|
||||
let ast = PARSER.parse(src);
|
||||
let mut links_offsets = vec![];
|
||||
ast.walk(|node, _depth| {
|
||||
if let Some(image) = node.cast::<T>() {
|
||||
@@ -94,6 +114,25 @@ impl UrlAndTitle for Link {
|
||||
}
|
||||
}
|
||||
|
||||
/// markdown-it normalizes links by default, which breaks the link rewriting. So we use a dummy
|
||||
/// formatter here which does nothing. Note this isnt actually used to render the markdown.
|
||||
#[derive(Debug)]
|
||||
struct NoopLinkFormatter;
|
||||
|
||||
impl LinkFormatter for NoopLinkFormatter {
|
||||
fn validate_link(&self, _url: &str) -> Option<()> {
|
||||
Some(())
|
||||
}
|
||||
|
||||
fn normalize_link(&self, url: &str) -> String {
|
||||
url.to_owned()
|
||||
}
|
||||
|
||||
fn normalize_link_text(&self, url: &str) -> String {
|
||||
url.to_owned()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
@@ -107,6 +146,12 @@ mod tests {
|
||||
|
||||
let links = find_urls::<Image>("");
|
||||
assert_eq!(vec![(8, 27)], links);
|
||||
|
||||
let links = find_urls::<Image>("");
|
||||
assert_eq!(vec![(22, 60)], links);
|
||||
|
||||
let links = find_urls::<Image>("");
|
||||
assert_eq!(vec![(8, 50)], links);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -152,7 +197,12 @@ mod tests {
|
||||
"custom emoji support",
|
||||
r#""#,
|
||||
r#""#
|
||||
)
|
||||
),
|
||||
(
|
||||
"image with special chars",
|
||||
"ითხოვს ",
|
||||
"ითხოვს ",
|
||||
),
|
||||
];
|
||||
|
||||
tests.iter().for_each(|&(msg, input, expected)| {
|
||||
|
||||
@@ -49,7 +49,6 @@ mod tests {
|
||||
|
||||
use super::*;
|
||||
use crate::utils::validation::check_urls_are_valid;
|
||||
use image_links::markdown_rewrite_image_links;
|
||||
use pretty_assertions::assert_eq;
|
||||
use regex::escape;
|
||||
|
||||
@@ -148,63 +147,6 @@ mod tests {
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_markdown_proxy_images() {
|
||||
let tests: Vec<_> =
|
||||
vec",
|
||||
"",
|
||||
),
|
||||
(
|
||||
"local image unproxied",
|
||||
"",
|
||||
"",
|
||||
),
|
||||
(
|
||||
"multiple image links",
|
||||
" ",
|
||||
" ",
|
||||
),
|
||||
(
|
||||
"empty link handled",
|
||||
"![image]()",
|
||||
"![image]()"
|
||||
),
|
||||
(
|
||||
"empty label handled",
|
||||
"",
|
||||
""
|
||||
),
|
||||
(
|
||||
"invalid image link removed",
|
||||
"",
|
||||
"![image]()"
|
||||
),
|
||||
(
|
||||
"label with nested markdown handled",
|
||||
"",
|
||||
""
|
||||
),
|
||||
(
|
||||
"custom emoji support",
|
||||
r#""#,
|
||||
r#""#
|
||||
)
|
||||
];
|
||||
|
||||
tests.iter().for_each(|&(msg, input, expected)| {
|
||||
let result = markdown_rewrite_image_links(input.to_string());
|
||||
|
||||
assert_eq!(
|
||||
result.0, expected,
|
||||
"Testing {}, with original input '{}'",
|
||||
msg, input
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
// This replicates the logic when saving url blocklist patterns and querying them.
|
||||
// Refer to lemmy_api_crud::site::update::update_site and
|
||||
// lemmy_api_common::utils::get_url_blocklist().
|
||||
|
||||
Reference in New Issue
Block a user