Skip to content

Commit

Permalink
Handle </p> and </br> in foreign contexts
Browse files Browse the repository at this point in the history
The HTML spec changed to handle `</p>` and `</br>` in foreign context
the same way `<p>` and `<br>` are.

The fragment case is handled identically to the nonfragment case now.
  • Loading branch information
stevecheckoway committed Jun 29, 2021
1 parent af4e4b2 commit b317bb8
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 13 deletions.
24 changes: 11 additions & 13 deletions gumbo-parser/src/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -4418,6 +4418,7 @@ static void handle_in_foreign_content(GumboParser* parser, GumboToken* token) {
|| token_has_attribute(token, "size")
)
)
|| tag_in(token, kEndTag, &(const TagSet) { TAG(BR), TAG(P) })
) {
/* Parse error */
parser_add_parse_error(parser, token);
Expand All @@ -4427,20 +4428,17 @@ static void handle_in_foreign_content(GumboParser* parser, GumboToken* token) {
* fragment parsing algorithm, then act as described in the "any other
* start tag" entry below.
*/
if (!is_fragment_parser(parser)) {
do {
pop_current_node(parser);
} while (
!(
is_mathml_integration_point(get_current_node(parser))
|| is_html_integration_point(get_current_node(parser))
|| get_current_node(parser)->v.element.tag_namespace == GUMBO_NAMESPACE_HTML
)
);
parser->_parser_state->_reprocess_current_token = true;
return;
while (
!(
is_mathml_integration_point(get_current_node(parser))
|| is_html_integration_point(get_current_node(parser))
|| get_current_node(parser)->v.element.tag_namespace == GUMBO_NAMESPACE_HTML
)
) {
pop_current_node(parser);
}
// This is a start tag so the next if's then branch will be taken.
handle_in_body(parser, token);
return;
}

if (token->type == GUMBO_TOKEN_START_TAG) {
Expand Down
20 changes: 20 additions & 0 deletions gumbo-parser/test/parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2220,4 +2220,24 @@ TEST_F(GumboParserTest, FragmentWithoutForm) {
EXPECT_EQ(0, GetChildCount(span));
}

TEST_F(GumboParserTest, ForeignFragment) {
ParseFragment("</p><foo>", "svg", GUMBO_NAMESPACE_SVG);
EXPECT_EQ(1, GetChildCount(root_));
GumboNode* html = GetChild(root_, 0);
ASSERT_EQ(GUMBO_NODE_ELEMENT, html->type);
EXPECT_EQ(GUMBO_TAG_HTML, html->v.element.tag);
EXPECT_EQ(2, GetChildCount(html));

ASSERT_EQ(2, GetChildCount(html));
GumboNode* p = GetChild(html, 0);
ASSERT_EQ(GUMBO_NODE_ELEMENT, p->type);
ASSERT_EQ(GUMBO_TAG_P, p->v.element.tag);
ASSERT_EQ(GUMBO_NAMESPACE_HTML, p->v.element.tag_namespace);

GumboNode* foo = GetChild(html, 1);
ASSERT_EQ(GUMBO_NODE_ELEMENT, foo->type);
ASSERT_EQ(std::string("foo"), foo->v.element.name);
ASSERT_EQ(GUMBO_NAMESPACE_SVG, foo->v.element.tag_namespace);
}

} // namespace

0 comments on commit b317bb8

Please sign in to comment.