diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 908e292d968ef..783b8b2db46a1 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -34,6 +34,7 @@ use std::str; use crate::clean::RenderedLink; use crate::doctest; use crate::html::escape::Escape; +use crate::html::format::Buffer; use crate::html::highlight; use crate::html::toc::TocBuilder; @@ -41,8 +42,6 @@ use pulldown_cmark::{ html, BrokenLink, CodeBlockKind, CowStr, Event, LinkType, Options, Parser, Tag, }; -use super::format::Buffer; - #[cfg(test)] mod tests; @@ -1086,7 +1085,7 @@ fn markdown_summary_with_limit( let mut stopped_early = false; fn push(s: &mut String, text_length: &mut usize, text: &str) { - s.push_str(text); + write!(s, "{}", Escape(text)).unwrap(); *text_length += text.len(); } diff --git a/src/librustdoc/html/markdown/tests.rs b/src/librustdoc/html/markdown/tests.rs index d10da64ccfaa5..1e4bdc2d15199 100644 --- a/src/librustdoc/html/markdown/tests.rs +++ b/src/librustdoc/html/markdown/tests.rs @@ -234,7 +234,17 @@ fn test_short_markdown_summary() { t("hello [Rust](https://www.rust-lang.org \"Rust\") :)", "hello Rust :)"); t("dud [link]", "dud [link]"); t("code `let x = i32;` ...", "code let x = i32; …"); - t("type `Type<'static>` ...", "type Type<'static> …"); + t("type `Type<'static>` ...", "type Type<'static> …"); + // Test to ensure escaping and length-limiting work well together. + // The output should be limited based on the input length, + // rather than the output, because escaped versions of characters + // are usually longer than how the character is actually displayed. + t( + "& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & &", + "& & & & & & & & & & & & \ + & & & & & & & & & & & & \ + & & & & & …", + ); t("# top header", "top header"); t("# top header\n\nfollowed by a paragraph", "top header"); t("## header", "header");