diff --git a/src/render.rs b/src/render.rs index c14920b..38bb835 100644 --- a/src/render.rs +++ b/src/render.rs @@ -149,13 +149,13 @@ pub fn markdown_to_html(markdown: &str) -> (String, Vec) { if title.is_empty() { html_output.push_str(&format!( "\"{}\"", - src, + html_escape(&src), html_escape(&alt) )); } else { html_output.push_str(&format!( "\"{}\"", - src, + html_escape(&src), html_escape(&alt), html_escape(&title) )); @@ -283,9 +283,13 @@ fn start_tag_to_html(tag: &Tag) -> String { dest_url, title, .. } => { if title.is_empty() { - format!("", dest_url) + format!("", html_escape(&dest_url)) } else { - format!("", dest_url, title) + format!( + "", + html_escape(&dest_url), + html_escape(&title) + ) } } Tag::Image { .. } => String::new(), // Handled separately in main loop @@ -459,4 +463,37 @@ Config details. // Consecutive special chars → single hyphen assert_eq!(slugify("A -- B"), "a-b"); } + + #[test] + fn test_link_url_escaping() { + // Quote-breaking attack + let md = r#"[click](">)"#; + let (html, _) = markdown_to_html(md); + assert!(!html.contains(")"#; + let (html, _) = markdown_to_html(md); + assert!(!html.contains("