From d2bb89bd441e8a90532675ab12b1c4fa0493cabf Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Thu, 17 Jan 2019 22:16:43 -0800 Subject: [PATCH 1/2] Fix undefined index notice when property lacks value --- lib/Sabberworm/CSS/Value/Value.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/Sabberworm/CSS/Value/Value.php b/lib/Sabberworm/CSS/Value/Value.php index 5c5504980..98b43d02f 100644 --- a/lib/Sabberworm/CSS/Value/Value.php +++ b/lib/Sabberworm/CSS/Value/Value.php @@ -55,6 +55,9 @@ public static function parseValue(ParserState $oParserState, $aListDelimiters = array_splice($aStack, $iStartPosition - 1, $iLength * 2 - 1, array($oList)); } } + if (!isset($aStack[0])) { + return null; + } return $aStack[0]; } From 2c61b738f9972ad5d58d3755296abf2f214b02da Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Tue, 29 Jan 2019 10:24:51 -0800 Subject: [PATCH 2/2] Throw UnexpectedTokenException when no property value present --- lib/Sabberworm/CSS/Value/Value.php | 3 +- tests/Sabberworm/CSS/ParserTest.php | 49 +++++++++++++++++++++++++---- 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/lib/Sabberworm/CSS/Value/Value.php b/lib/Sabberworm/CSS/Value/Value.php index 98b43d02f..ae361dd7c 100644 --- a/lib/Sabberworm/CSS/Value/Value.php +++ b/lib/Sabberworm/CSS/Value/Value.php @@ -3,6 +3,7 @@ namespace Sabberworm\CSS\Value; use Sabberworm\CSS\Parsing\ParserState; +use Sabberworm\CSS\Parsing\UnexpectedTokenException; use Sabberworm\CSS\Renderable; abstract class Value implements Renderable { @@ -56,7 +57,7 @@ public static function parseValue(ParserState $oParserState, $aListDelimiters = } } if (!isset($aStack[0])) { - return null; + throw new UnexpectedTokenException(" {$oParserState->peek()} ", $oParserState->peek(1, -1) . $oParserState->peek(2), 'literal', $oParserState->currentLine()); } return $aStack[0]; } diff --git a/tests/Sabberworm/CSS/ParserTest.php b/tests/Sabberworm/CSS/ParserTest.php index ea8bbdf5e..0922b11ec 100644 --- a/tests/Sabberworm/CSS/ParserTest.php +++ b/tests/Sabberworm/CSS/ParserTest.php @@ -472,26 +472,63 @@ function testTrailingWhitespace() { } /** - * @expectedException Sabberworm\CSS\Parsing\UnexpectedTokenException - */ + * @expectedException \Sabberworm\CSS\Parsing\UnexpectedTokenException + */ function testCharsetFailure1() { $this->parsedStructureForFile('-charset-after-rule', Settings::create()->withLenientParsing(false)); } /** - * @expectedException Sabberworm\CSS\Parsing\UnexpectedTokenException - */ + * @expectedException \Sabberworm\CSS\Parsing\UnexpectedTokenException + */ function testCharsetFailure2() { $this->parsedStructureForFile('-charset-in-block', Settings::create()->withLenientParsing(false)); } /** - * @expectedException Sabberworm\CSS\Parsing\SourceException - */ + * @expectedException \Sabberworm\CSS\Parsing\SourceException + */ function testUnopenedClosingBracketFailure() { $this->parsedStructureForFile('unopened-close-brackets', Settings::create()->withLenientParsing(false)); } + /** + * Ensure that a missing property value raises an exception. + * + * @expectedException \Sabberworm\CSS\Parsing\UnexpectedTokenException + * @covers \Sabberworm\CSS\Value\Value::parseValue() + */ + function testMissingPropertyValueStrict() { + $this->parsedStructureForFile('missing-property-value', Settings::create()->withLenientParsing(false)); + } + + /** + * Ensure that a missing property value is ignored when in lenient parsing mode. + * + * @covers \Sabberworm\CSS\Value\Value::parseValue() + */ + function testMissingPropertyValueLenient() { + $parsed = $this->parsedStructureForFile('missing-property-value', Settings::create()->withLenientParsing(true)); + $rulesets = $parsed->getAllRuleSets(); + $this->assertCount( 1, $rulesets ); + $block = $rulesets[0]; + $this->assertTrue( $block instanceof DeclarationBlock ); + $this->assertEquals( array( 'div' ), $block->getSelectors() ); + $rules = $block->getRules(); + $this->assertCount( 1, $rules ); + $rule = $rules[0]; + $this->assertEquals( 'display', $rule->getRule() ); + $this->assertEquals( 'inline-block', $rule->getValue() ); + } + + /** + * Parse structure for file. + * + * @param string $sFileName Filename. + * @param null|obJeCt $oSettings Settings. + * + * @return CSSList\Document Parsed document. + */ function parsedStructureForFile($sFileName, $oSettings = null) { $sFile = dirname(__FILE__) . '/../../files' . DIRECTORY_SEPARATOR . "$sFileName.css"; $oParser = new Parser(file_get_contents($sFile), $oSettings);