Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions Build/phpstan/phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,30 @@ parameters:
count: 1
path: ../../src/Parsing/ParserState.php

-
message: '#^Function preg_match is unsafe to use\. It can return FALSE instead of throwing an exception\. Please add ''use function Safe\\preg_match;'' at the beginning of the file to use the variant provided by the ''thecodingmachine/safe'' library\.$#'
identifier: theCodingMachineSafe.function
count: 1
path: ../../src/Property/Declaration.php

-
message: '#^Function preg_match is unsafe to use\. It can return FALSE instead of throwing an exception\. Please add ''use function Safe\\preg_match;'' at the beginning of the file to use the variant provided by the ''thecodingmachine/safe'' library\.$#'
identifier: theCodingMachineSafe.function
count: 1
path: ../../src/Property/Selector.php

-
message: '#^Function preg_match is unsafe to use\. It can return FALSE instead of throwing an exception\. Please add ''use function Safe\\preg_match;'' at the beginning of the file to use the variant provided by the ''thecodingmachine/safe'' library\.$#'
identifier: theCodingMachineSafe.function
count: 1
path: ../../src/Property/Selector/CompoundSelector.php

-
message: '#^Function preg_match_all is unsafe to use\. It can return FALSE instead of throwing an exception\. Please add ''use function Safe\\preg_match_all;'' at the beginning of the file to use the variant provided by the ''thecodingmachine/safe'' library\.$#'
identifier: theCodingMachineSafe.function
count: 2
path: ../../src/Property/Selector/SpecificityCalculator.php

-
message: '#^Parameter \#2 \$arguments of class Sabberworm\\CSS\\Value\\CSSFunction constructor expects array\<Sabberworm\\CSS\\Value\\Value\|string\>\|Sabberworm\\CSS\\Value\\RuleValueList, Sabberworm\\CSS\\Value\\Value\|string given\.$#'
identifier: argument.type
Expand Down
6 changes: 3 additions & 3 deletions src/Property/Declaration.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@
use Sabberworm\CSS\Value\RuleValueList;
use Sabberworm\CSS\Value\Value;

use function Safe\preg_match;

/**
* `Declaration`s just have a string key (the property name) and a 'Value'.
*
Expand Down Expand Up @@ -105,7 +103,9 @@ public static function parse(ParserState $parserState, array $commentsBefore = [
*/
private static function getDelimitersForPropertyValue(string $propertyName): array
{
if (preg_match('/^font($|-)/', $propertyName) === 1) {
$matchResult = \preg_match('/^font($|-)/', $propertyName);
\assert(\is_int($matchResult));
if ($matchResult === 1) {
return [',', '/', ' '];
}

Expand Down
7 changes: 4 additions & 3 deletions src/Property/Selector.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
use Sabberworm\CSS\Settings;
use Sabberworm\CSS\ShortClassNameProvider;

use function Safe\preg_match;

/**
* Class representing a single CSS selector. Selectors have to be split by the comma prior to being passed into this
* class.
Expand Down Expand Up @@ -68,7 +66,10 @@ class Selector implements Renderable
public static function isValid(string $selector): bool
{
// Note: We need to use `static::` here as the constant is overridden in the `KeyframeSelector` class.
$numberOfMatches = preg_match(static::SELECTOR_VALIDATION_RX, $selector);
$numberOfMatches = \preg_match(static::SELECTOR_VALIDATION_RX, $selector);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This pattern is overridden in KeyframeSelector, so I've added a test for this in both Selector and KeyframeSelector. Both patterns fail the same way on invalid UTF-8

if (!\is_int($numberOfMatches)) {
throw new \RuntimeException('The selector is not valid UTF-8.', 1787284398);
}

return $numberOfMatches === 1;
}
Expand Down
7 changes: 4 additions & 3 deletions src/Property/Selector/CompoundSelector.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@
use Sabberworm\CSS\Parsing\UnexpectedTokenException;
use Sabberworm\CSS\ShortClassNameProvider;

use function Safe\preg_match;

/**
* Class representing a CSS compound selector.
* Selectors have to be split at combinators (space, `>`, `+`, `~`) before being passed to this class.
Expand Down Expand Up @@ -277,7 +275,10 @@ public function getArrayRepresentation(): array

private static function isValid(string $value): bool
{
$numberOfMatches = preg_match(self::SELECTOR_VALIDATION_RX, $value);
$numberOfMatches = \preg_match(self::SELECTOR_VALIDATION_RX, $value);
if (!\is_int($numberOfMatches)) {
throw new \RuntimeException('The selector is not valid UTF-8.', 1787283476);
}

return $numberOfMatches === 1;
}
Expand Down
8 changes: 4 additions & 4 deletions src/Property/Selector/SpecificityCalculator.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@

namespace Sabberworm\CSS\Property\Selector;

use function Safe\preg_match_all;

/**
* Utility class to calculate the specificity of a CSS selector.
*
Expand Down Expand Up @@ -65,8 +63,10 @@ public static function calculate(string $selector): int
/// @todo should exclude \# as well as "#"
$matches = null;
$b = \substr_count($selector, '#');
$c = preg_match_all(self::NON_ID_ATTRIBUTES_AND_PSEUDO_CLASSES_RX, $selector, $matches);
$d = preg_match_all(self::ELEMENTS_AND_PSEUDO_ELEMENTS_RX, $selector, $matches);
$c = \preg_match_all(self::NON_ID_ATTRIBUTES_AND_PSEUDO_CLASSES_RX, $selector, $matches);
\assert(\is_int($c));
$d = \preg_match_all(self::ELEMENTS_AND_PSEUDO_ELEMENTS_RX, $selector, $matches);
\assert(\is_int($d));
self::$cache[$selector] = ($a * 1000) + ($b * 100) + ($c * 10) + $d;
}

Expand Down
12 changes: 12 additions & 0 deletions tests/Unit/Property/KeyframeSelectorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,16 @@ public function getArrayRepresentationIncludesComponent(): void

self::assertSame('50%', $result['components'][0]['value']);
}

/**
* @test
*/
public function isValidThrowsForSelectorThatIsNotValidUtf8(): void
{
$this->expectException(\RuntimeException::class);
$this->expectExceptionMessage('The selector is not valid UTF-8.');
$this->expectExceptionCode(1787284398);

KeyframeSelector::isValid("a\xFF");
}
}
12 changes: 12 additions & 0 deletions tests/Unit/Property/Selector/CompoundSelectorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,18 @@ public function constructorThrowsExceptionWithInvalidValue(string $value): void
new CompoundSelector($value);
}

/**
* @test
*/
public function constructorThrowsForValueThatIsNotValidUtf8(): void
{
$this->expectException(\RuntimeException::class);
$this->expectExceptionMessage('The selector is not valid UTF-8.');
$this->expectExceptionCode(1787283476);

new CompoundSelector("a\xFF");
}

/**
* @test
*
Expand Down
12 changes: 12 additions & 0 deletions tests/Unit/Property/SelectorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,18 @@ public function isValidForInvalidSelectorReturnsFalse(string $selector): void
self::assertFalse(Selector::isValid($selector));
}

/**
* @test
*/
public function isValidThrowsForSelectorThatIsNotValidUtf8(): void
{
$this->expectException(\RuntimeException::class);
$this->expectExceptionMessage('The selector is not valid UTF-8.');
$this->expectExceptionCode(1787284398);

Selector::isValid("a\xFF");
}

/**
* @test
*/
Expand Down