Skip to content

Commit 1e19013

Browse files
committed
Add a check for unclosed elements on the stack
This checks for any unclosed elements when processing is finished. This is intended to detect invalid HTML in the source, or bugs in the tree builder. Raw HTML elements generate a warning (which in the future will be a configurable lint). All other sync errors are internal errors as they are not expected, and it would be helpful to know if they ever happen.
1 parent 4417f8c commit 1e19013

File tree

2 files changed

+38
-0
lines changed

2 files changed

+38
-0
lines changed

crates/mdbook-html/src/html/tree.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,7 @@ where
378378
}
379379
}
380380
}
381+
self.finish_stack();
381382
self.collect_footnote_defs();
382383
}
383384

@@ -736,6 +737,40 @@ where
736737
output
737738
}
738739

740+
/// Deals with any unclosed elements on the stack.
741+
fn finish_stack(&mut self) {
742+
while let Some(node_id) = self.tag_stack.pop() {
743+
let node = self.tree.get(node_id).unwrap().value();
744+
match node {
745+
Node::Fragment => {}
746+
Node::Element(el) => {
747+
if el.was_raw {
748+
warn!(
749+
"unclosed HTML tag `<{}>` found in `{}`",
750+
el.name.local,
751+
self.options.path.display()
752+
);
753+
} else {
754+
panic!(
755+
"internal error: expected empty tag stack.\n
756+
path: `{}`\n\
757+
element={el:?}",
758+
self.options.path.display()
759+
);
760+
}
761+
}
762+
node => {
763+
panic!(
764+
"internal error: expected empty tag stack.\n
765+
path: `{}`\n\
766+
node={node:?}",
767+
self.options.path.display()
768+
);
769+
}
770+
}
771+
}
772+
}
773+
739774
/// Appends a new footnote reference.
740775
fn footnote_reference(&mut self, name: CowStr<'event>) {
741776
let len = self.footnote_numbers.len() + 1;

tests/testsuite/rendering.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,9 @@ fn unclosed_html_tags() {
252252
cmd.expect_stderr(str![[r#"
253253
INFO Book building has started
254254
INFO Running the html backend
255+
WARN unclosed HTML tag `<i>` found in `chapter_1.md`
256+
WARN unclosed HTML tag `<span>` found in `chapter_1.md`
257+
WARN unclosed HTML tag `<div>` found in `chapter_1.md`
255258
INFO HTML book written to `[ROOT]/book`
256259
257260
"#]]);

0 commit comments

Comments
 (0)