diff --git a/lib/Sabberworm/CSS/Parsing/ParserState.php b/lib/Sabberworm/CSS/Parsing/ParserState.php index ad79820a6..daf4919ce 100644 --- a/lib/Sabberworm/CSS/Parsing/ParserState.php +++ b/lib/Sabberworm/CSS/Parsing/ParserState.php @@ -55,7 +55,11 @@ public function parseIdentifier($bIgnoreCase = true) { } $sCharacter = null; while (($sCharacter = $this->parseCharacter(true)) !== null) { - $sResult .= $sCharacter; + if (preg_match('/[a-zA-Z0-9\x{00A0}-\x{FFFF}_-]/Sux', $sCharacter)) { + $sResult .= $sCharacter; + } else { + $sResult .= '\\' . $sCharacter; + } } if ($bIgnoreCase) { $sResult = $this->strtolower($sResult); diff --git a/tests/Sabberworm/CSS/ParserTest.php b/tests/Sabberworm/CSS/ParserTest.php index ea34f2e70..3f5b279de 100644 --- a/tests/Sabberworm/CSS/ParserTest.php +++ b/tests/Sabberworm/CSS/ParserTest.php @@ -466,6 +466,12 @@ function testSelectorEscapesInFile() { $this->assertSame($sExpected, $oDoc->render()); } + function testIdentifierEscapesInFile() { + $oDoc = $this->parsedStructureForFile('identifier-escapes', Settings::create()->withMultibyteSupport(true)); + $sExpected = 'div {font: 14px Font Awesome\ 5 Pro;font: 14px Font Awesome\} 5 Pro;font: 14px Font Awesome\; 5 Pro;f\;ont: 14px Font Awesome\; 5 Pro;}'; + $this->assertSame($sExpected, $oDoc->render()); + } + function testSelectorIgnoresInFile() { $oDoc = $this->parsedStructureForFile('selector-ignores', Settings::create()->withMultibyteSupport(true)); $sExpected = '.some[selectors-may=\'contain-a-{\'] {} diff --git a/tests/files/identifier-escapes.css b/tests/files/identifier-escapes.css new file mode 100644 index 000000000..8829e7a82 --- /dev/null +++ b/tests/files/identifier-escapes.css @@ -0,0 +1,6 @@ +div { + font: 14px Font Awesome\ 5 Pro; + font: 14px Font Awesome\} 5 Pro; + font: 14px Font Awesome\; 5 Pro; + f\;ont: 14px Font Awesome\; 5 Pro; +}