From 735a77f38f43bc6ab47ee6c67147f9aeee39e886 Mon Sep 17 00:00:00 2001 From: raxbg Date: Fri, 20 Dec 2019 16:53:50 +0200 Subject: [PATCH 1/3] Improve parsing of invalid identifiers by preserving valid @ rules --- lib/Sabberworm/CSS/CSSList/CSSList.php | 3 ++- lib/Sabberworm/CSS/Parsing/ParserState.php | 12 ++++++++++++ lib/Sabberworm/CSS/RuleSet/DeclarationBlock.php | 4 ++++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/lib/Sabberworm/CSS/CSSList/CSSList.php b/lib/Sabberworm/CSS/CSSList/CSSList.php index aebefffc..5c826e55 100644 --- a/lib/Sabberworm/CSS/CSSList/CSSList.php +++ b/lib/Sabberworm/CSS/CSSList/CSSList.php @@ -89,7 +89,8 @@ private static function parseListItem(ParserState $oParserState, CSSList $oList) } else { if ($bIsRoot) { if ($oParserState->getSettings()->bLenientParsing) { - return DeclarationBlock::parse($oParserState); + $oParserState->bufferForSelector(1); + return false; } else { throw new SourceException("Unopened {", $oParserState->currentLine()); } diff --git a/lib/Sabberworm/CSS/Parsing/ParserState.php b/lib/Sabberworm/CSS/Parsing/ParserState.php index ad79820a..455ddf72 100644 --- a/lib/Sabberworm/CSS/Parsing/ParserState.php +++ b/lib/Sabberworm/CSS/Parsing/ParserState.php @@ -18,6 +18,7 @@ class ParserState { private $sCharset; private $iLength; private $iLineNo; + private $sSelectorBuffer; public function __construct($sText, Settings $oParserSettings, $iLineNo = 1) { $this->oParserSettings = $oParserSettings; @@ -25,6 +26,7 @@ public function __construct($sText, Settings $oParserSettings, $iLineNo = 1) { $this->iCurrentPosition = 0; $this->iLineNo = $iLineNo; $this->setCharset($this->oParserSettings->sDefaultCharset); + $this->sSelectorBuffer = ""; } public function setCharset($sCharset) { @@ -48,6 +50,16 @@ public function getSettings() { return $this->oParserSettings; } + public function bufferForSelector($iCount) { + $this->sSelectorBuffer .= $this->consume($iCount); + } + + public function consumeSelectorBuffer() { + $sResult = $this->sSelectorBuffer; + $this->sSelectorBuffer = ""; + return $sResult; + } + public function parseIdentifier($bIgnoreCase = true) { $sResult = $this->parseCharacter(true); if ($sResult === null) { diff --git a/lib/Sabberworm/CSS/RuleSet/DeclarationBlock.php b/lib/Sabberworm/CSS/RuleSet/DeclarationBlock.php index a1142bef..d6d850e6 100644 --- a/lib/Sabberworm/CSS/RuleSet/DeclarationBlock.php +++ b/lib/Sabberworm/CSS/RuleSet/DeclarationBlock.php @@ -33,6 +33,10 @@ public static function parse(ParserState $oParserState, $oList = NULL) { $oResult = new DeclarationBlock($oParserState->currentLine()); try { $aSelectorParts = array(); + $sSelectorBuffer = $oParserState->consumeSelectorBuffer(); + if ($sSelectorBuffer) { + $aSelectorParts[] = $sSelectorBuffer; + } $sStringWrapperChar = false; do { $aSelectorParts[] = $oParserState->consume(1) . $oParserState->consumeUntil(array('{', '}', '\'', '"'), false, false, $aComments); From cc6cf2f54bb6629637235a734c1a70d827ab2a00 Mon Sep 17 00:00:00 2001 From: raxbg Date: Fri, 20 Dec 2019 17:06:15 +0200 Subject: [PATCH 2/3] Add test for the resolved issue --- tests/Sabberworm/CSS/ParserTest.php | 5 +++++ tests/files/invalid-selectors-3.css | 13 +++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 tests/files/invalid-selectors-3.css diff --git a/tests/Sabberworm/CSS/ParserTest.php b/tests/Sabberworm/CSS/ParserTest.php index ea34f2e7..128f0014 100644 --- a/tests/Sabberworm/CSS/ParserTest.php +++ b/tests/Sabberworm/CSS/ParserTest.php @@ -448,6 +448,11 @@ function testInvalidSelectorsInFile() { html[dir="rtl"] .super-menu > li:last-of-type {border-left-width: 0;}} body {background-color: red;}'; $this->assertSame($sExpected, $oDoc->render()); + + $oDoc = $this->parsedStructureForFile('invalid-selectors-3', Settings::create()->withMultibyteSupport(true)); + $sExpected = '#test {color: #fff;} +@media only screen and (max-width:30000px) {#test2 {color: #fff;}}'; + $this->assertSame($sExpected, $oDoc->render()); } function testSelectorEscapesInFile() { diff --git a/tests/files/invalid-selectors-3.css b/tests/files/invalid-selectors-3.css new file mode 100644 index 00000000..6ed13410 --- /dev/null +++ b/tests/files/invalid-selectors-3.css @@ -0,0 +1,13 @@ +#test { + color: #fff; +} +} + +@media only screen and (max-width:30000px) { + #test { + color: #fff; + } + #test2 { + color: #fff; + } +} From ad7fd1499e8a782603b4282e34d71b966254d5a0 Mon Sep 17 00:00:00 2001 From: Ivailo Hristov Date: Sat, 17 Sep 2022 23:17:50 +0300 Subject: [PATCH 3/3] Fixes for CI --- src/Parsing/ParserState.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Parsing/ParserState.php b/src/Parsing/ParserState.php index b4c4cbd8..56df883c 100644 --- a/src/Parsing/ParserState.php +++ b/src/Parsing/ParserState.php @@ -48,7 +48,7 @@ class ParserState * @var int */ private $iLineNo; - private $sSelectorBuffer; + private $sSelectorBuffer; /** * @param string $sText the complete CSS as text (i.e., usually the contents of a CSS file) @@ -61,7 +61,7 @@ public function __construct($sText, Settings $oParserSettings, $iLineNo = 1) $this->iCurrentPosition = 0; $this->iLineNo = $iLineNo; $this->setCharset($this->oParserSettings->sDefaultCharset); - $this->sSelectorBuffer = ""; + $this->sSelectorBuffer = ""; } /**