From 8c96b8174bd7b5c0bacc029b1a0255cf8a667bc3 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sat, 30 May 2020 16:22:25 +0200 Subject: [PATCH] LibWeb: Handle AAA situation where there's no formatting element found In this case, we're supposed to return from the AAA and then jump to a different behavior in the "in body" insertion mode. So now we do that. --- .../LibWeb/Parser/HTMLDocumentParser.cpp | 25 +++++++++---------- Libraries/LibWeb/Parser/HTMLDocumentParser.h | 8 +++++- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/Libraries/LibWeb/Parser/HTMLDocumentParser.cpp b/Libraries/LibWeb/Parser/HTMLDocumentParser.cpp index a5e1ecf1d8..fa9b921c86 100644 --- a/Libraries/LibWeb/Parser/HTMLDocumentParser.cpp +++ b/Libraries/LibWeb/Parser/HTMLDocumentParser.cpp @@ -605,7 +605,7 @@ Create: goto Advance; } -void HTMLDocumentParser::run_the_adoption_agency_algorithm(HTMLToken& token) +HTMLDocumentParser::AdoptionAgencyAlgorithmOutcome HTMLDocumentParser::run_the_adoption_agency_algorithm(HTMLToken& token) { auto subject = token.tag_name(); @@ -614,23 +614,20 @@ void HTMLDocumentParser::run_the_adoption_agency_algorithm(HTMLToken& token) // then pop the current node off the stack of open elements, and return. if (current_node().tag_name() == subject && !m_list_of_active_formatting_elements.contains(current_node())) { m_stack_of_open_elements.pop(); - return; + return AdoptionAgencyAlgorithmOutcome::DoNothing; } size_t outer_loop_counter = 0; //OuterLoop: if (outer_loop_counter >= 8) - return; + return AdoptionAgencyAlgorithmOutcome::DoNothing; ++outer_loop_counter; auto formatting_element = m_list_of_active_formatting_elements.last_element_with_tag_name_before_marker(subject); - if (!formatting_element) { - // FIXME: If there is no such element, then return and instead act as - // described in the "any other end tag" entry above. - TODO(); - } + if (!formatting_element) + return AdoptionAgencyAlgorithmOutcome::RunAnyOtherEndTagSteps; if (!m_stack_of_open_elements.contains(*formatting_element)) { PARSE_ERROR(); @@ -641,7 +638,7 @@ void HTMLDocumentParser::run_the_adoption_agency_algorithm(HTMLToken& token) if (!m_stack_of_open_elements.has_in_scope(*formatting_element)) { PARSE_ERROR(); - return; + return AdoptionAgencyAlgorithmOutcome::DoNothing; } if (formatting_element != ¤t_node()) { @@ -656,7 +653,7 @@ void HTMLDocumentParser::run_the_adoption_agency_algorithm(HTMLToken& token) m_stack_of_open_elements.pop(); m_list_of_active_formatting_elements.remove(*formatting_element); - return; + return AdoptionAgencyAlgorithmOutcome::DoNothing; } // FIXME: Implement the rest of the AAA :^) @@ -1052,7 +1049,8 @@ void HTMLDocumentParser::handle_in_body(HTMLToken& token) if (token.is_start_tag() && token.tag_name() == "a") { if (auto* element = m_list_of_active_formatting_elements.last_element_with_tag_name_before_marker("a")) { PARSE_ERROR(); - run_the_adoption_agency_algorithm(token); + if (run_the_adoption_agency_algorithm(token) == AdoptionAgencyAlgorithmOutcome::RunAnyOtherEndTagSteps) + goto AnyOtherEndTag; m_list_of_active_formatting_elements.remove(*element); m_stack_of_open_elements.elements().remove_first_matching([&](auto& entry) { return entry.ptr() == element; @@ -1076,7 +1074,8 @@ void HTMLDocumentParser::handle_in_body(HTMLToken& token) } if (token.is_end_tag() && token.tag_name().is_one_of("a", "b", "big", "code", "em", "font", "i", "nobr", "s", "small", "strike", "strong", "tt", "u")) { - run_the_adoption_agency_algorithm(token); + if (run_the_adoption_agency_algorithm(token) == AdoptionAgencyAlgorithmOutcome::RunAnyOtherEndTagSteps) + goto AnyOtherEndTag; return; } @@ -1210,8 +1209,8 @@ void HTMLDocumentParser::handle_in_body(HTMLToken& token) return; } - // Any other end tag if (token.is_end_tag()) { + AnyOtherEndTag: RefPtr node; for (ssize_t i = m_stack_of_open_elements.elements().size() - 1; i >= 0; --i) { node = m_stack_of_open_elements.elements()[i]; diff --git a/Libraries/LibWeb/Parser/HTMLDocumentParser.h b/Libraries/LibWeb/Parser/HTMLDocumentParser.h index 9ac19091fc..3c0870ec61 100644 --- a/Libraries/LibWeb/Parser/HTMLDocumentParser.h +++ b/Libraries/LibWeb/Parser/HTMLDocumentParser.h @@ -114,7 +114,13 @@ private: void decrement_script_nesting_level(); size_t script_nesting_level() const { return m_script_nesting_level; } void reset_the_insertion_mode_appropriately(); - void run_the_adoption_agency_algorithm(HTMLToken&); + + enum AdoptionAgencyAlgorithmOutcome { + DoNothing, + RunAnyOtherEndTagSteps, + }; + + AdoptionAgencyAlgorithmOutcome run_the_adoption_agency_algorithm(HTMLToken&); void clear_the_stack_back_to_a_table_context(); void clear_the_stack_back_to_a_table_body_context(); void clear_the_stack_back_to_a_table_row_context();