From b7a77c2b46905158d900c29b1e0d6c96b1332732 Mon Sep 17 00:00:00 2001 From: Carson McManus Date: Fri, 20 Sep 2024 07:57:00 -0400 Subject: [PATCH] fix(parser/html): fix incorrect parsing when text starts with a quote --- crates/biome_html_parser/src/syntax/mod.rs | 2 +- .../html_specs/ok/element_list.html.snap | 19 ++- .../html_specs/ok/element_list2.html.snap | 17 +-- .../tests/html_specs/ok/quote-in-child.html | 1 + .../html_specs/ok/quote-in-child.html.snap | 117 ++++++++++++++++++ 5 files changed, 132 insertions(+), 24 deletions(-) create mode 100644 crates/biome_html_parser/tests/html_specs/ok/quote-in-child.html create mode 100644 crates/biome_html_parser/tests/html_specs/ok/quote-in-child.html.snap diff --git a/crates/biome_html_parser/src/syntax/mod.rs b/crates/biome_html_parser/src/syntax/mod.rs index 1e14a5e0e233..fc67c3795240 100644 --- a/crates/biome_html_parser/src/syntax/mod.rs +++ b/crates/biome_html_parser/src/syntax/mod.rs @@ -144,7 +144,7 @@ fn parse_closing_element(p: &mut HtmlParser) -> ParsedSyntax { p.error(void_element_should_not_have_closing_tag(p, p.cur_range()).into_diagnostic(p)); } let _name = parse_literal(p); - p.bump(T![>]); + p.bump_with_context(T![>], HtmlLexContext::OutsideTag); Present(m.complete(p, HTML_CLOSING_ELEMENT)) } diff --git a/crates/biome_html_parser/tests/html_specs/ok/element_list.html.snap b/crates/biome_html_parser/tests/html_specs/ok/element_list.html.snap index 6bebcf50a0dc..b800f844b075 100644 --- a/crates/biome_html_parser/tests/html_specs/ok/element_list.html.snap +++ b/crates/biome_html_parser/tests/html_specs/ok/element_list.html.snap @@ -82,10 +82,7 @@ HtmlRoot { }, }, HtmlContent { - value_token: HTML_LITERAL@38..46 "some" [Newline("\n"), Whitespace("\t\t")] [Whitespace(" ")], - }, - HtmlContent { - value_token: HTML_LITERAL@46..50 "text" [] [], + value_token: HTML_LITERAL@38..50 "some text" [Newline("\n"), Whitespace("\t\t")] [], }, HtmlElement { opening_element: HtmlOpeningElement { @@ -419,11 +416,9 @@ HtmlRoot { 2: HTML_NAME@34..37 0: HTML_LITERAL@34..37 "div" [] [] 3: R_ANGLE@37..38 ">" [] [] - 2: HTML_CONTENT@38..46 - 0: HTML_LITERAL@38..46 "some" [Newline("\n"), Whitespace("\t\t")] [Whitespace(" ")] - 3: HTML_CONTENT@46..50 - 0: HTML_LITERAL@46..50 "text" [] [] - 4: HTML_ELEMENT@50..64 + 2: HTML_CONTENT@38..50 + 0: HTML_LITERAL@38..50 "some text" [Newline("\n"), Whitespace("\t\t")] [] + 3: HTML_ELEMENT@50..64 0: HTML_OPENING_ELEMENT@50..58 0: L_ANGLE@50..54 "<" [Newline("\n"), Whitespace("\t\t")] [] 1: HTML_NAME@54..57 @@ -437,7 +432,7 @@ HtmlRoot { 2: HTML_NAME@60..63 0: HTML_LITERAL@60..63 "div" [] [] 3: R_ANGLE@63..64 ">" [] [] - 5: HTML_ELEMENT@64..78 + 4: HTML_ELEMENT@64..78 0: HTML_OPENING_ELEMENT@64..72 0: L_ANGLE@64..68 "<" [Newline("\n"), Whitespace("\t\t")] [] 1: HTML_NAME@68..71 @@ -451,7 +446,7 @@ HtmlRoot { 2: HTML_NAME@74..77 0: HTML_LITERAL@74..77 "div" [] [] 3: R_ANGLE@77..78 ">" [] [] - 6: HTML_ELEMENT@78..92 + 5: HTML_ELEMENT@78..92 0: HTML_OPENING_ELEMENT@78..86 0: L_ANGLE@78..82 "<" [Newline("\n"), Whitespace("\t\t")] [] 1: HTML_NAME@82..85 @@ -465,7 +460,7 @@ HtmlRoot { 2: HTML_NAME@88..91 0: HTML_LITERAL@88..91 "div" [] [] 3: R_ANGLE@91..92 ">" [] [] - 7: HTML_ELEMENT@92..409 + 6: HTML_ELEMENT@92..409 0: HTML_OPENING_ELEMENT@92..100 0: L_ANGLE@92..96 "<" [Newline("\n"), Whitespace("\t\t")] [] 1: HTML_NAME@96..99 diff --git a/crates/biome_html_parser/tests/html_specs/ok/element_list2.html.snap b/crates/biome_html_parser/tests/html_specs/ok/element_list2.html.snap index 168cfa10749a..9abb2029f647 100644 --- a/crates/biome_html_parser/tests/html_specs/ok/element_list2.html.snap +++ b/crates/biome_html_parser/tests/html_specs/ok/element_list2.html.snap @@ -48,10 +48,7 @@ HtmlRoot { }, }, HtmlContent { - value_token: HTML_LITERAL@21..27 "some" [Newline("\n")] [Whitespace(" ")], - }, - HtmlContent { - value_token: HTML_LITERAL@27..31 "text" [] [], + value_token: HTML_LITERAL@21..31 "some text" [Newline("\n")] [], }, HtmlElement { opening_element: HtmlOpeningElement { @@ -140,11 +137,9 @@ HtmlRoot { 2: HTML_NAME@17..20 0: HTML_LITERAL@17..20 "div" [] [] 3: R_ANGLE@20..21 ">" [] [] - 3: HTML_CONTENT@21..27 - 0: HTML_LITERAL@21..27 "some" [Newline("\n")] [Whitespace(" ")] - 4: HTML_CONTENT@27..31 - 0: HTML_LITERAL@27..31 "text" [] [] - 5: HTML_ELEMENT@31..43 + 3: HTML_CONTENT@21..31 + 0: HTML_LITERAL@21..31 "some text" [Newline("\n")] [] + 4: HTML_ELEMENT@31..43 0: HTML_OPENING_ELEMENT@31..37 0: L_ANGLE@31..33 "<" [Newline("\n")] [] 1: HTML_NAME@33..36 @@ -158,7 +153,7 @@ HtmlRoot { 2: HTML_NAME@39..42 0: HTML_LITERAL@39..42 "div" [] [] 3: R_ANGLE@42..43 ">" [] [] - 6: HTML_ELEMENT@43..55 + 5: HTML_ELEMENT@43..55 0: HTML_OPENING_ELEMENT@43..49 0: L_ANGLE@43..45 "<" [Newline("\n")] [] 1: HTML_NAME@45..48 @@ -172,7 +167,7 @@ HtmlRoot { 2: HTML_NAME@51..54 0: HTML_LITERAL@51..54 "div" [] [] 3: R_ANGLE@54..55 ">" [] [] - 7: HTML_ELEMENT@55..67 + 6: HTML_ELEMENT@55..67 0: HTML_OPENING_ELEMENT@55..61 0: L_ANGLE@55..57 "<" [Newline("\n")] [] 1: HTML_NAME@57..60 diff --git a/crates/biome_html_parser/tests/html_specs/ok/quote-in-child.html b/crates/biome_html_parser/tests/html_specs/ok/quote-in-child.html new file mode 100644 index 000000000000..b501a5681a15 --- /dev/null +++ b/crates/biome_html_parser/tests/html_specs/ok/quote-in-child.html @@ -0,0 +1 @@ +

"Foo" is the title.

diff --git a/crates/biome_html_parser/tests/html_specs/ok/quote-in-child.html.snap b/crates/biome_html_parser/tests/html_specs/ok/quote-in-child.html.snap new file mode 100644 index 000000000000..b0f0e54538de --- /dev/null +++ b/crates/biome_html_parser/tests/html_specs/ok/quote-in-child.html.snap @@ -0,0 +1,117 @@ +--- +source: crates/biome_html_parser/tests/spec_test.rs +expression: snapshot +--- +## Input + +```html +

"Foo" is the title.

+ +``` + + +## AST + +``` +HtmlRoot { + bom_token: missing (optional), + directive: missing (optional), + html: HtmlElementList [ + HtmlElement { + opening_element: HtmlOpeningElement { + l_angle_token: L_ANGLE@0..1 "<" [] [], + name: HtmlName { + value_token: HTML_LITERAL@1..2 "p" [] [], + }, + attributes: HtmlAttributeList [], + r_angle_token: R_ANGLE@2..3 ">" [] [], + }, + children: HtmlElementList [ + HtmlContent { + value_token: HTML_LITERAL@3..4 "\"" [] [], + }, + HtmlElement { + opening_element: HtmlOpeningElement { + l_angle_token: L_ANGLE@4..5 "<" [] [], + name: HtmlName { + value_token: HTML_LITERAL@5..9 "span" [] [], + }, + attributes: HtmlAttributeList [], + r_angle_token: R_ANGLE@9..10 ">" [] [], + }, + children: HtmlElementList [ + HtmlContent { + value_token: HTML_LITERAL@10..13 "Foo" [] [], + }, + ], + closing_element: HtmlClosingElement { + l_angle_token: L_ANGLE@13..14 "<" [] [], + slash_token: SLASH@14..15 "/" [] [], + name: HtmlName { + value_token: HTML_LITERAL@15..19 "span" [] [], + }, + r_angle_token: R_ANGLE@19..20 ">" [] [], + }, + }, + HtmlContent { + value_token: HTML_LITERAL@20..35 "\" is the title." [] [], + }, + ], + closing_element: HtmlClosingElement { + l_angle_token: L_ANGLE@35..36 "<" [] [], + slash_token: SLASH@36..37 "/" [] [], + name: HtmlName { + value_token: HTML_LITERAL@37..38 "p" [] [], + }, + r_angle_token: R_ANGLE@38..39 ">" [] [], + }, + }, + ], + eof_token: EOF@39..40 "" [Newline("\n")] [], +} +``` + +## CST + +``` +0: HTML_ROOT@0..40 + 0: (empty) + 1: (empty) + 2: HTML_ELEMENT_LIST@0..39 + 0: HTML_ELEMENT@0..39 + 0: HTML_OPENING_ELEMENT@0..3 + 0: L_ANGLE@0..1 "<" [] [] + 1: HTML_NAME@1..2 + 0: HTML_LITERAL@1..2 "p" [] [] + 2: HTML_ATTRIBUTE_LIST@2..2 + 3: R_ANGLE@2..3 ">" [] [] + 1: HTML_ELEMENT_LIST@3..35 + 0: HTML_CONTENT@3..4 + 0: HTML_LITERAL@3..4 "\"" [] [] + 1: HTML_ELEMENT@4..20 + 0: HTML_OPENING_ELEMENT@4..10 + 0: L_ANGLE@4..5 "<" [] [] + 1: HTML_NAME@5..9 + 0: HTML_LITERAL@5..9 "span" [] [] + 2: HTML_ATTRIBUTE_LIST@9..9 + 3: R_ANGLE@9..10 ">" [] [] + 1: HTML_ELEMENT_LIST@10..13 + 0: HTML_CONTENT@10..13 + 0: HTML_LITERAL@10..13 "Foo" [] [] + 2: HTML_CLOSING_ELEMENT@13..20 + 0: L_ANGLE@13..14 "<" [] [] + 1: SLASH@14..15 "/" [] [] + 2: HTML_NAME@15..19 + 0: HTML_LITERAL@15..19 "span" [] [] + 3: R_ANGLE@19..20 ">" [] [] + 2: HTML_CONTENT@20..35 + 0: HTML_LITERAL@20..35 "\" is the title." [] [] + 2: HTML_CLOSING_ELEMENT@35..39 + 0: L_ANGLE@35..36 "<" [] [] + 1: SLASH@36..37 "/" [] [] + 2: HTML_NAME@37..38 + 0: HTML_LITERAL@37..38 "p" [] [] + 3: R_ANGLE@38..39 ">" [] [] + 3: EOF@39..40 "" [Newline("\n")] [] + +```