Skip to content

Commit 07e7275

Browse files
authored
Merge pull request #1376 from dtolnay/html
Escape `<` and `>` in rendered toc to match handlebars' escaping in <title>
2 parents 58f66a1 + c712ba7 commit 07e7275

File tree

1 file changed

+18
-2
lines changed
  • src/renderer/html_handlebars/helpers

1 file changed

+18
-2
lines changed

src/renderer/html_handlebars/helpers/toc.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use std::collections::BTreeMap;
2+
use std::io;
23
use std::path::Path;
34

45
use crate::utils;
@@ -102,7 +103,7 @@ impl HelperDef for RenderToc {
102103
// Part title
103104
if let Some(title) = item.get("part") {
104105
out.write("<li class=\"part-title\">")?;
105-
out.write(title)?;
106+
write_escaped(out, title)?;
106107
out.write("</li>")?;
107108
continue;
108109
}
@@ -160,7 +161,7 @@ impl HelperDef for RenderToc {
160161
html::push_html(&mut markdown_parsed_name, parser);
161162

162163
// write to the handlebars template
163-
out.write(&markdown_parsed_name)?;
164+
write_escaped(out, &markdown_parsed_name)?;
164165
}
165166

166167
if path_exists {
@@ -204,3 +205,18 @@ fn write_li_open_tag(
204205
li.push_str("\">");
205206
out.write(&li)
206207
}
208+
209+
fn write_escaped(out: &mut dyn Output, mut title: &str) -> io::Result<()> {
210+
let needs_escape: &[char] = &['<', '>'];
211+
while let Some(next) = title.find(needs_escape) {
212+
out.write(&title[..next])?;
213+
match title.as_bytes()[next] {
214+
b'<' => out.write("&lt;")?,
215+
b'>' => out.write("&gt;")?,
216+
_ => unreachable!(),
217+
}
218+
title = &title[next + 1..];
219+
}
220+
out.write(title)?;
221+
Ok(())
222+
}

0 commit comments

Comments
 (0)