Skip to content

Commit 47fc80b

Browse files
committedOct 17, 2023
fix #3426: improve invalid url() token parsing
1 parent d6973b9 commit 47fc80b

File tree

2 files changed

+30
-7
lines changed

2 files changed

+30
-7
lines changed
 

‎internal/css_parser/css_parser.go

+25-6
Original file line numberDiff line numberDiff line change
@@ -974,12 +974,31 @@ func (p *parser) parseURLOrString() (string, logger.Range, bool) {
974974
case css_lexer.TFunction:
975975
if strings.EqualFold(p.decoded(), "url") {
976976
matchingLoc := logger.Loc{Start: p.current().Range.End() - 1}
977-
p.advance()
978-
t = p.current()
979-
text := p.decoded()
980-
if p.expect(css_lexer.TString) {
981-
p.expectWithMatchingLoc(css_lexer.TCloseParen, matchingLoc)
982-
return text, t.Range, true
977+
i := p.index + 1
978+
979+
// Skip over whitespace
980+
for p.at(i).Kind == css_lexer.TWhitespace {
981+
i++
982+
}
983+
984+
// Consume a string
985+
if p.at(i).Kind == css_lexer.TString {
986+
stringIndex := i
987+
i++
988+
989+
// Skip over whitespace
990+
for p.at(i).Kind == css_lexer.TWhitespace {
991+
i++
992+
}
993+
994+
// Consume a closing parenthesis
995+
if close := p.at(i).Kind; close == css_lexer.TCloseParen || close == css_lexer.TEndOfFile {
996+
t := p.at(stringIndex)
997+
text := t.DecodedText(p.source.Contents)
998+
p.index = i
999+
p.expectWithMatchingLoc(css_lexer.TCloseParen, matchingLoc)
1000+
return text, t.Range, true
1001+
}
9831002
}
9841003
}
9851004
}

‎internal/css_parser/css_parser_test.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -1302,15 +1302,19 @@ func TestAtImport(t *testing.T) {
13021302
expectPrinted(t, "@import url();", "@import \"\";\n", "")
13031303
expectPrinted(t, "@import url(foo.css);", "@import \"foo.css\";\n", "")
13041304
expectPrinted(t, "@import url(foo.css) ;", "@import \"foo.css\";\n", "")
1305+
expectPrinted(t, "@import url( foo.css );", "@import \"foo.css\";\n", "")
13051306
expectPrinted(t, "@import url(\"foo.css\");", "@import \"foo.css\";\n", "")
13061307
expectPrinted(t, "@import url(\"foo.css\") ;", "@import \"foo.css\";\n", "")
1308+
expectPrinted(t, "@import url( \"foo.css\" );", "@import \"foo.css\";\n", "")
13071309
expectPrinted(t, "@import url(\"foo.css\") print;", "@import \"foo.css\" print;\n", "")
13081310
expectPrinted(t, "@import url(\"foo.css\") screen and (orientation:landscape);", "@import \"foo.css\" screen and (orientation:landscape);\n", "")
13091311

13101312
expectPrinted(t, "@import;", "@import;\n", "<stdin>: WARNING: Expected URL token but found \";\"\n")
13111313
expectPrinted(t, "@import ;", "@import;\n", "<stdin>: WARNING: Expected URL token but found \";\"\n")
13121314
expectPrinted(t, "@import \"foo.css\"", "@import \"foo.css\";\n", "<stdin>: WARNING: Expected \";\" but found end of file\n")
1313-
expectPrinted(t, "@import url(\"foo.css\";", "@import \"foo.css\";\n", "<stdin>: WARNING: Expected \")\" to go with \"(\"\n<stdin>: NOTE: The unbalanced \"(\" is here:\n")
1315+
expectPrinted(t, "@import url(\"foo.css\" extra-stuff);", "@import url(\"foo.css\" extra-stuff);\n", "<stdin>: WARNING: Expected URL token but found \"url(\"\n")
1316+
expectPrinted(t, "@import url(\"foo.css\";", "@import url(\"foo.css\";);\n",
1317+
"<stdin>: WARNING: Expected URL token but found \"url(\"\n<stdin>: WARNING: Expected \")\" to go with \"(\"\n<stdin>: NOTE: The unbalanced \"(\" is here:\n")
13141318
expectPrinted(t, "@import noturl(\"foo.css\");", "@import noturl(\"foo.css\");\n", "<stdin>: WARNING: Expected URL token but found \"noturl(\"\n")
13151319
expectPrinted(t, "@import url(foo.css", "@import \"foo.css\";\n", `<stdin>: WARNING: Expected ")" to end URL token
13161320
<stdin>: NOTE: The unbalanced "(" is here:

0 commit comments

Comments
 (0)