From d6973b938e4622db0f692d6eac846af60f7515e2 Mon Sep 17 00:00:00 2001 From: Evan Wallace Date: Mon, 16 Oct 2023 21:58:34 -0400 Subject: [PATCH] css: fix url token backtracking with leading space --- internal/css_lexer/css_lexer.go | 13 +++++++++++++ internal/css_parser/css_parser_test.go | 21 +++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/internal/css_lexer/css_lexer.go b/internal/css_lexer/css_lexer.go index b63ff733def..9e8c0883abc 100644 --- a/internal/css_lexer/css_lexer.go +++ b/internal/css_lexer/css_lexer.go @@ -763,12 +763,25 @@ func (lexer *lexer) consumeIdentLike() T { if len(name) == 3 { u, r, l := name[0], name[1], name[2] if (u == 'u' || u == 'U') && (r == 'r' || r == 'R') && (l == 'l' || l == 'L') { + // Save state + approximateNewlineCount := lexer.approximateNewlineCount + codePoint := lexer.codePoint + tokenRangeLen := lexer.Token.Range.Len + current := lexer.current + + // Check to see if this is a URL token instead of a function for isWhitespace(lexer.codePoint) { lexer.step() } if lexer.codePoint != '"' && lexer.codePoint != '\'' { return lexer.consumeURL(matchingLoc) } + + // Restore state (i.e. backtrack) + lexer.approximateNewlineCount = approximateNewlineCount + lexer.codePoint = codePoint + lexer.Token.Range.Len = tokenRangeLen + lexer.current = current } } return TFunction diff --git a/internal/css_parser/css_parser_test.go b/internal/css_parser/css_parser_test.go index bdfb631e12d..f0f62752885 100644 --- a/internal/css_parser/css_parser_test.go +++ b/internal/css_parser/css_parser_test.go @@ -375,6 +375,27 @@ func TestNumber(t *testing.T) { } } +func TestURL(t *testing.T) { + expectPrinted(t, "a { background: url(foo.png) }", "a {\n background: url(foo.png);\n}\n", "") + expectPrinted(t, "a { background: url('foo.png') }", "a {\n background: url(foo.png);\n}\n", "") + expectPrinted(t, "a { background: url(\"foo.png\") }", "a {\n background: url(foo.png);\n}\n", "") + expectPrinted(t, "a { background: url(\"foo.png\" ) }", "a {\n background: url(foo.png);\n}\n", "") + expectPrinted(t, "a { background: url(\"foo.png\"\t) }", "a {\n background: url(foo.png);\n}\n", "") + expectPrinted(t, "a { background: url(\"foo.png\"\r) }", "a {\n background: url(foo.png);\n}\n", "") + expectPrinted(t, "a { background: url(\"foo.png\"\n) }", "a {\n background: url(foo.png);\n}\n", "") + expectPrinted(t, "a { background: url(\"foo.png\"\f) }", "a {\n background: url(foo.png);\n}\n", "") + expectPrinted(t, "a { background: url(\"foo.png\"\r\n) }", "a {\n background: url(foo.png);\n}\n", "") + expectPrinted(t, "a { background: url( \"foo.png\") }", "a {\n background: url(foo.png);\n}\n", "") + expectPrinted(t, "a { background: url(\t\"foo.png\") }", "a {\n background: url(foo.png);\n}\n", "") + expectPrinted(t, "a { background: url(\r\"foo.png\") }", "a {\n background: url(foo.png);\n}\n", "") + expectPrinted(t, "a { background: url(\n\"foo.png\") }", "a {\n background: url(foo.png);\n}\n", "") + expectPrinted(t, "a { background: url(\f\"foo.png\") }", "a {\n background: url(foo.png);\n}\n", "") + expectPrinted(t, "a { background: url(\r\n\"foo.png\") }", "a {\n background: url(foo.png);\n}\n", "") + expectPrinted(t, "a { background: url( \"foo.png\" ) }", "a {\n background: url(foo.png);\n}\n", "") + expectPrinted(t, "a { background: url(\"foo.png\" extra-stuff) }", "a {\n background: url(\"foo.png\" extra-stuff);\n}\n", "") + expectPrinted(t, "a { background: url( \"foo.png\" extra-stuff ) }", "a {\n background: url(\"foo.png\" extra-stuff);\n}\n", "") +} + func TestHexColor(t *testing.T) { // "#RGBA"