Skip to content
Open
Show file tree
Hide file tree
Changes from 6 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
3 changes: 3 additions & 0 deletions Build/phpstan/phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ parameters:
-
message: '#^Call to static method PHPUnit\\Framework\\Assert\:\:assertInstanceOf\(\) .* will always evaluate to#'
path: '%currentWorkingDirectory%/tests/'
-
identifier: theCodingMachineSafe.function
path: '%currentWorkingDirectory%/tests/'

services:
-
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ Please also have a look at our

### Changed

- Remove `thecodingmachine/safe` dependency (#1484)

### Deprecated

### Removed
Expand Down
8 changes: 5 additions & 3 deletions bin/quickdump.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@

use Sabberworm\CSS\Parser;

use function Safe\file_get_contents;

/**
* This script is used for generating the examples in the README.
*/

require_once(__DIR__ . '/../vendor/autoload.php');

$source = file_get_contents('php://stdin');
/** @phpstan-ignore theCodingMachineSafe.function */
$source = \file_get_contents('php://stdin');
if ($source === false) {
throw new \RuntimeException('Unexpected error');
}
$parser = new Parser($source);

$document = $parser->parse();
Expand Down
3 changes: 1 addition & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@
"homepage": "https://www.sabberworm.com/blog/2010/6/10/php-css-parser",
"require": {
"php": "^7.2.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0",
"ext-iconv": "*",
"thecodingmachine/safe": "^1.3 || ^2.5 || ^3.4"
"ext-iconv": "*"
},
"require-dev": {
"php-parallel-lint/php-parallel-lint": "1.4.0",
Expand Down
9 changes: 6 additions & 3 deletions src/CSSList/CSSList.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@
use Sabberworm\CSS\Value\URL;
use Sabberworm\CSS\Value\Value;

use function Safe\preg_match;

/**
* This is the most generic container available. It can contain `DeclarationBlock`s (rule sets with a selector),
* `RuleSet`s as well as other `CSSList` objects.
Expand Down Expand Up @@ -252,7 +250,12 @@ private static function identifierIs(string $identifier, string $match): bool
return true;
}

return preg_match("/^(-\\w+-)?$match$/i", $identifier) === 1;
/** @phpstan-ignore theCodingMachineSafe.function */
$matchResult = \preg_match("/^(-\\w+-)?$match$/i", $identifier);
if ($matchResult === false) {
throw new \RuntimeException('Unexpected error');
}
return $matchResult === 1;
}

/**
Expand Down
51 changes: 40 additions & 11 deletions src/Parsing/ParserState.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,6 @@
use Sabberworm\CSS\Comment\Comment;
use Sabberworm\CSS\Settings;

use function Safe\iconv;
use function Safe\preg_match;
use function Safe\preg_split;

/**
* @internal since 8.7.0
*/
Expand Down Expand Up @@ -120,7 +116,12 @@ public function parseIdentifier(bool $ignoreCase = true): string
throw new UnexpectedTokenException('', $this->peek(5), 'identifier', $this->lineNumber);
}
while (!$this->isEnd() && ($character = $this->parseCharacter(true)) !== null) {
if (preg_match('/[a-zA-Z0-9\\x{00A0}-\\x{FFFF}_-]/Sux', $character) !== 0) {
/** @phpstan-ignore theCodingMachineSafe.function */
$matchResult = \preg_match('/[a-zA-Z0-9\\x{00A0}-\\x{FFFF}_-]/Sux', $character);
if ($matchResult === false) {
throw new \RuntimeException('Unexpected error');
}
if ($matchResult !== 0) {
$result .= $character;
} else {
$result .= '\\' . $character;
Expand All @@ -144,13 +145,23 @@ public function parseCharacter(bool $isForIdentifier): ?string
if ($this->comes('\\n') || $this->comes('\\r')) {
return '';
}
if (preg_match('/[0-9a-fA-F]/Su', $this->peek()) === 0) {
/** @phpstan-ignore theCodingMachineSafe.function */
$hexMatch = \preg_match('/[0-9a-fA-F]/Su', $this->peek());
if ($hexMatch === false) {
throw new \RuntimeException('Unexpected error');
}
if ($hexMatch === 0) {
return $this->consume(1);
}
$hexCodePoint = $this->consumeExpression('/^[0-9a-fA-F]{1,6}/u', 6);
if ($this->strlen($hexCodePoint) < 6) {
// Consume whitespace after incomplete unicode escape
if (preg_match('/\\s/isSu', $this->peek()) !== 0) {
/** @phpstan-ignore theCodingMachineSafe.function */
$whitespaceMatch = \preg_match('/\\s/isSu', $this->peek());
if ($whitespaceMatch === false) {
throw new \RuntimeException('Unexpected error');
}
if ($whitespaceMatch !== 0) {
if ($this->comes('\\r\\n')) {
$this->consume(2);
} else {
Expand All @@ -164,7 +175,12 @@ public function parseCharacter(bool $isForIdentifier): ?string
$utf32EncodedCharacter .= \chr($codePoint & 0xff);
$codePoint = $codePoint >> 8;
}
return iconv('utf-32le', $this->charset, $utf32EncodedCharacter);
/** @phpstan-ignore theCodingMachineSafe.function */
$character = \iconv('utf-32le', $this->charset, $utf32EncodedCharacter);
if ($character === false) {
throw new \RuntimeException('Unexpected error');
}
return $character;
}
if ($isForIdentifier) {
$peek = \ord($this->peek());
Expand Down Expand Up @@ -204,7 +220,15 @@ public function consumeWhiteSpace(array &$comments = []): string
{
$consumed = '';
do {
while (preg_match('/\\s/isSu', $this->peek()) === 1) {
while (true) {
/** @phpstan-ignore theCodingMachineSafe.function */
$whitespaceCheck = \preg_match('/\\s/isSu', $this->peek());
if ($whitespaceCheck === false) {
throw new \RuntimeException('Unexpected error');
}
if ($whitespaceCheck !== 1) {
break;
}
$consumed .= $this->consume(1);
}
if ($this->parserSettings->usesLenientParsing()) {
Expand Down Expand Up @@ -318,7 +342,8 @@ public function consumeExpression(string $expression, ?int $maximumLength = null
{
$matches = null;
$input = ($maximumLength !== null) ? $this->peek($maximumLength) : $this->inputLeft();
if (preg_match($expression, $input, $matches, PREG_OFFSET_CAPTURE) !== 1) {
/** @phpstan-ignore theCodingMachineSafe.function */
if (\preg_match($expression, $input, $matches, PREG_OFFSET_CAPTURE) !== 1) {
throw new UnexpectedTokenException($expression, $this->peek(5), 'expression', $this->lineNumber);

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

No need to check for false here. If this preg_match returns false then we'll already throw an exception

}
Comment thread
SjorsO marked this conversation as resolved.

Expand Down Expand Up @@ -467,7 +492,11 @@ private function strsplit(string $string): array
{
if ($this->parserSettings->hasMultibyteSupport()) {
if ($this->streql($this->charset, 'utf-8')) {
$result = preg_split('//u', $string, -1, PREG_SPLIT_NO_EMPTY);
/** @phpstan-ignore theCodingMachineSafe.function */
$result = \preg_split('//u', $string, -1, PREG_SPLIT_NO_EMPTY);
if ($result === false) {
throw new \RuntimeException('Unexpected error');
}
} else {
$length = \mb_strlen($string, $this->charset);
$result = [];
Expand Down
9 changes: 6 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,12 @@ public static function parse(ParserState $parserState, array $commentsBefore = [
*/
private static function getDelimitersForPropertyValue(string $propertyName): array
{
if (preg_match('/^font($|-)/', $propertyName) === 1) {
/** @phpstan-ignore theCodingMachineSafe.function */
$matchResult = \preg_match('/^font($|-)/', $propertyName);
if ($matchResult === false) {
throw new \RuntimeException('Unexpected error');
}
if ($matchResult === 1) {
return [',', '/', ' '];
}

Expand Down
8 changes: 5 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,11 @@ 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);
/** @phpstan-ignore theCodingMachineSafe.function */
$numberOfMatches = \preg_match(static::SELECTOR_VALIDATION_RX, $selector);
if ($numberOfMatches === false) {
throw new \RuntimeException('Unexpected error');
}

return $numberOfMatches === 1;
}
Expand Down
8 changes: 5 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,11 @@ public function getArrayRepresentation(): array

private static function isValid(string $value): bool
{
$numberOfMatches = preg_match(self::SELECTOR_VALIDATION_RX, $value);
/** @phpstan-ignore theCodingMachineSafe.function */
$numberOfMatches = \preg_match(self::SELECTOR_VALIDATION_RX, $value);
if ($numberOfMatches === false) {
throw new \RuntimeException('Unexpected error');
}

return $numberOfMatches === 1;
}
Expand Down
14 changes: 10 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,16 @@ 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);
/** @phpstan-ignore theCodingMachineSafe.function */
$c = \preg_match_all(self::NON_ID_ATTRIBUTES_AND_PSEUDO_CLASSES_RX, $selector, $matches);
if ($c === false) {
throw new \RuntimeException('Unexpected error');
}
/** @phpstan-ignore theCodingMachineSafe.function */
$d = \preg_match_all(self::ELEMENTS_AND_PSEUDO_ELEMENTS_RX, $selector, $matches);
if ($d === false) {
throw new \RuntimeException('Unexpected error');
}
self::$cache[$selector] = ($a * 1000) + ($b * 100) + ($c * 10) + $d;
}

Expand Down
7 changes: 4 additions & 3 deletions src/Rule/Rule.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@

use Sabberworm\CSS\Property\Declaration;

use function Safe\class_alias;

// @phpstan-ignore function.impossibleType
if (!\class_exists(Rule::class, false) && !\interface_exists(Rule::class, false)) {
class_alias(Declaration::class, Rule::class);
/** @phpstan-ignore theCodingMachineSafe.function */
if (\class_alias(Declaration::class, Rule::class) === false) {
throw new \RuntimeException('Unexpected error');
}
// The test is expected to evaluate to false,
// but allows for the deprecation notice to be picked up by IDEs like PHPStorm.
// @phpstan-ignore booleanNot.alwaysTrue, booleanAnd.alwaysTrue, function.impossibleType
Expand Down
7 changes: 4 additions & 3 deletions src/RuleSet/RuleContainer.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@

namespace Sabberworm\CSS\RuleSet;

use function Safe\class_alias;

// @phpstan-ignore function.impossibleType
if (!\class_exists(RuleContainer::class, false) && !\interface_exists(RuleContainer::class, false)) {
class_alias(DeclarationList::class, RuleContainer::class);
/** @phpstan-ignore theCodingMachineSafe.function */
if (\class_alias(DeclarationList::class, RuleContainer::class) === false) {
throw new \RuntimeException('Unexpected error');
}
// The test is expected to evaluate to false,
// but allows for the deprecation notice to be picked up by IDEs like PHPStorm.
// @phpstan-ignore booleanNot.alwaysTrue, booleanAnd.alwaysTrue, function.impossibleType
Expand Down
12 changes: 9 additions & 3 deletions src/Value/CSSString.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@
use Sabberworm\CSS\Parsing\UnexpectedTokenException;
use Sabberworm\CSS\ShortClassNameProvider;

use function Safe\preg_match;

/**
* This class is a wrapper for quoted strings to distinguish them from keywords.
*
Expand Down Expand Up @@ -58,7 +56,15 @@ public static function parse(ParserState $parserState): CSSString
$result = '';
if ($quote === null) {
// Unquoted strings end in whitespace or with braces, brackets, parentheses
while (preg_match('/[\\s{}()<>\\[\\]]/isu', $parserState->peek()) === 0) {
while (true) {
/** @phpstan-ignore theCodingMachineSafe.function */
$matchResult = \preg_match('/[\\s{}()<>\\[\\]]/isu', $parserState->peek());
if ($matchResult === false) {
throw new \RuntimeException('Unexpected error');
}
if ($matchResult !== 0) {
break;
}
$result .= $parserState->parseCharacter(false);
}
} else {
Expand Down
8 changes: 4 additions & 4 deletions src/Value/CalcFunction.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
use Sabberworm\CSS\Parsing\UnexpectedEOFException;
use Sabberworm\CSS\Parsing\UnexpectedTokenException;

use function Safe\preg_match;

class CalcFunction extends CSSFunction
{
private const T_OPERAND = 1;
Expand Down Expand Up @@ -62,8 +60,10 @@ public static function parse(ParserState $parserState, bool $ignoreCase = false)
if (\in_array($parserState->peek(), $operators, true)) {
if (($parserState->comes('-') || $parserState->comes('+'))) {
if (
preg_match('/\\s/', $parserState->peek(1, -1)) !== 1
|| preg_match('/\\s/', $parserState->peek(1, 1)) !== 1
/** @phpstan-ignore theCodingMachineSafe.function */
\preg_match('/\\s/', $parserState->peek(1, -1)) !== 1
/** @phpstan-ignore theCodingMachineSafe.function */
|| \preg_match('/\\s/', $parserState->peek(1, 1)) !== 1
Comment thread
SjorsO marked this conversation as resolved.
) {
throw new UnexpectedTokenException(
" {$parserState->peek()} ",
Expand Down
26 changes: 20 additions & 6 deletions src/Value/Size.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@
use Sabberworm\CSS\Parsing\UnexpectedTokenException;
use Sabberworm\CSS\ShortClassNameProvider;

use function Safe\preg_match;
use function Safe\preg_replace;

/**
* A `Size` consists of a numeric `size` value and a unit.
*/
Expand Down Expand Up @@ -200,10 +197,27 @@ public function render(OutputFormat $outputFormat): string
{
$locale = \localeconv();
$decimalPoint = \preg_quote($locale['decimal_point'], '/');
$size = preg_match('/[\\d\\.]+e[+-]?\\d+/i', (string) $this->size) === 1
? preg_replace("/$decimalPoint?0+$/", '', \sprintf('%f', $this->size)) : (string) $this->size;
/** @phpstan-ignore theCodingMachineSafe.function */
$matchResult = \preg_match('/[\\d\\.]+e[+-]?\\d+/i', (string) $this->size);
if ($matchResult === false) {
throw new \RuntimeException('Unexpected error');
}
if ($matchResult === 1) {
/** @phpstan-ignore theCodingMachineSafe.function */
$size = \preg_replace("/$decimalPoint?0+$/", '', \sprintf('%f', $this->size));
if ($size === null) {
throw new \RuntimeException('Unexpected error');
}
} else {
$size = (string) $this->size;
}

return preg_replace(["/$decimalPoint/", '/^(-?)0\\./'], ['.', '$1.'], $size) . ($this->unit ?? '');
/** @phpstan-ignore theCodingMachineSafe.function */
$result = \preg_replace(["/$decimalPoint/", '/^(-?)0\\./'], ['.', '$1.'], $size);
if ($result === null) {
throw new \RuntimeException('Unexpected error');
}
return $result . ($this->unit ?? '');
}

/**
Expand Down
Loading