sabberworm / PHP-CSS-Parser

A Parser for CSS Files written in PHP. Allows extraction of CSS files into a data structure, manipulation of said structure and output as (optimized) CSS

Home Page:http://www.sabberworm.com/blog/2010/6/10/php-css-parser

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

declaration block (rule) with only a comment causes UnexpectedTokenException

mikkorantalainen opened this issue · comments

Test case with version 8.2.0

html
{
	/* nothing but a comment here */
}

causes following exception

Identifier expected. Got “}” [line no: 4] in ...lib/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Parser.php:215
Stack trace:
#0 ...lib/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Parser.php(359): Sabberworm\\CSS\\Parser->parseIdentifier()
#1 ...lib/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Parser.php(348): Sabberworm\\CSS\\Parser->parseRule()
#2 ...lib/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Parser.php(318): Sabberworm\\CSS\\Parser->parseRuleSet(Object(Sabberworm\\CSS\\RuleSet\\DeclarationBlock))
#3 ...lib/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Parser.php(147): Sabberworm\\CSS\\Parser->parseSelector()
#4 ...lib/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Parser.php(104): Sabberworm\\CSS\\Parser->parseListItem(Object(Sabberworm\\CSS\\CSSList\\Document), true)
#5 ...lib/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Parser.php(90): Sabberworm\\CSS\\Parser->parseList(Object(Sabberworm\\CSS\\CSSList\\Document), true)
#6 ...lib/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Parser.php(85): Sabberworm\\CSS\\Parser->parseDocument(Object(Sabberworm\\CSS\\CSSList\\Document))
#7 .../CssParser.php(90): Sabberworm\\CSS\\Parser->parse()

A declaration block with multiple comments fails in similar way. If a declaration block contains any property before or after the comment, everything seems to work fine.

Maybe modify parseRule() in Parser.php to start with:

	private function parseRule() {
		$aComments = $this->consumeWhiteSpace();
		if ($this->comes('}'))
			return false;
		$oRule = new Rule($this->parseIdentifier(), $this->iLineNo);

?

The above suggested change will lose the parsed comments but class parseRule() is expected to return a rule which currently always requires at least one declaration if I've understood correctly.

This is still a problem with version 8.3.0. Quick hack which will drop the problematic comment:

diff --git i/lib/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Rule/Rule.php w/lib/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Rule/Rule.php
index 3fa031b..212011c 100644
--- i/lib/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Rule/Rule.php
+++ w/lib/vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Rule/Rule.php
@@ -32,6 +32,8 @@ public function __construct($sRule, $iLineNo = 0) {
 
        public static function parse(ParserState $oParserState) {
                $aComments = $oParserState->consumeWhiteSpace();
+               if ($oParserState->comes('}'))
+                       return false;
                $oRule = new Rule($oParserState->parseIdentifier(), $oParserState->currentLine());
                $oRule->setComments($aComments);
                $oRule->addComments($oParserState->consumeWhiteSpace());

A proper fix would require e.g. creating new class EmptyRule which is allowed to contain only a single comment and emit that instead for this special case. I don't know how much side-effects that might cause.