Skip to content

Commit

Permalink
html2: Handle </br> correctly
Browse files Browse the repository at this point in the history
  • Loading branch information
robinlinden committed Jan 6, 2025
1 parent 1d405d3 commit c2866ec
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 8 deletions.
16 changes: 12 additions & 4 deletions html2/parser_states.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2023-2024 Robin Lindén <[email protected]>
// SPDX-FileCopyrightText: 2023-2025 Robin Lindén <[email protected]>
//
// SPDX-License-Identifier: BSD-2-Clause

Expand Down Expand Up @@ -901,9 +901,17 @@ std::optional<InsertionMode> InBody::process(IActions &a, html2::Token const &to
"keygen",
"wbr",
});
if (start != nullptr && is_in_array<kImmediatelyPoppedElements>(start->tag_name)) {
a.reconstruct_active_formatting_elements();
a.insert_element_for(*start);
auto is_bad_br_end_tag = end != nullptr && end->tag_name == "br";
if ((start != nullptr && is_in_array<kImmediatelyPoppedElements>(start->tag_name)) || (is_bad_br_end_tag)) {
if (is_bad_br_end_tag) {
// Parse error.
a.reconstruct_active_formatting_elements();
a.insert_element_for(html2::StartTagToken{.tag_name = "br"});
} else {
a.reconstruct_active_formatting_elements();
a.insert_element_for(*start);
}

a.pop_current_node();
// TODO(robinlinden): Acknowledge the token's self-closing flag, if it is set.
a.set_frameset_ok(false);
Expand Down
25 changes: 21 additions & 4 deletions html2/parser_states_test.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2023-2024 Robin Lindén <[email protected]>
// SPDX-FileCopyrightText: 2023-2025 Robin Lindén <[email protected]>
//
// SPDX-License-Identifier: BSD-2-Clause

Expand Down Expand Up @@ -314,9 +314,15 @@ void in_head_noscript_tests(etest::Suite &s) {

s.add_test("InHeadNoScript: br", [](etest::IActions &a) {
auto res = parse("<noscript></br>", {});
auto noscript = dom::Element{"noscript"};
a.expect_eq(res.document.html(),
dom::Element{"html", {}, {dom::Element{"head", {}, {std::move(noscript)}}, dom::Element{"body"}}});
dom::Element{
"html",
{},
{
dom::Element{"head", {}, {dom::Element{"noscript"}}},
dom::Element{"body", {}, {dom::Element{"br"}}},
},
});
});

s.add_test("InHeadNoScript: noscript", [](etest::IActions &a) {
Expand Down Expand Up @@ -388,7 +394,12 @@ void after_head_tests(etest::Suite &s) {

s.add_test("AfterHead: </br>", [](etest::IActions &a) {
auto res = parse("<head></head></br>", {});
a.expect_eq(res.document.html(), dom::Element{"html", {}, {dom::Element{"head"}, dom::Element{"body"}}});
a.expect_eq(res.document.html(),
dom::Element{
"html",
{},
{dom::Element{"head"}, dom::Element{"body", {}, {dom::Element{"br"}}}},
});
});

s.add_test("AfterHead: </error>", [](etest::IActions &a) {
Expand Down Expand Up @@ -515,6 +526,12 @@ void in_body_tests(etest::Suite &s) {
a.expect_eq(body, dom::Element{"body", {}, {dom::Element{"p"}, dom::Element{"hr"}}});
});

s.add_test("InBody: </br>", [](etest::IActions &a) {
auto res = parse("<body></br>", {});
auto const &body = std::get<dom::Element>(res.document.html().children.at(1));
a.expect_eq(body, dom::Element{"body", {}, {dom::Element{"br"}}});
});

s.add_test("InBody: <template> doesn't crash", [](etest::IActions &) {
std::ignore = parse("<body><template>", {}); //
});
Expand Down

0 comments on commit c2866ec

Please sign in to comment.