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
18 changes: 18 additions & 0 deletions Build/phpstan/phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,12 @@ parameters:
count: 1
path: ../../src/Value/CSSFunction.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/Value/CSSString.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
Expand All @@ -102,6 +108,18 @@ parameters:
count: 3
path: ../../src/Value/Color.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/Value/Size.php

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

-
message: '#^Strict comparison using \!\=\= between non\-empty\-string and null will always evaluate to true\.$#'
identifier: notIdentical.alwaysTrue
Expand Down
11 changes: 8 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,14 @@ 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) {
$matchResult = \preg_match('/[\\s{}()<>\\[\\]]/isu', $parserState->peek());
if (!\is_int($matchResult)) {
throw new \RuntimeException('The CSS is not valid UTF-8.', 1787548272);
}
if ($matchResult !== 0) {
break;
}
$result .= $parserState->parseCharacter(false);
}
} else {
Expand Down
18 changes: 12 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,19 @@ 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;
$matchResult = \preg_match('/[\\d\\.]+e[+-]?\\d+/i', (string) $this->size);
\assert(\is_int($matchResult));
if ($matchResult === 1) {
$size = \preg_replace("/$decimalPoint?0+$/", '', \sprintf('%f', $this->size));
\assert(\is_string($size));
} else {
$size = (string) $this->size;
}

$renderedSize = \preg_replace(["/$decimalPoint/", '/^(-?)0\\./'], ['.', '$1.'], $size);
\assert(\is_string($renderedSize));

return preg_replace(["/$decimalPoint/", '/^(-?)0\\./'], ['.', '$1.'], $size) . ($this->unit ?? '');
return $renderedSize . ($this->unit ?? '');
}

/**
Expand Down
16 changes: 16 additions & 0 deletions tests/Unit/Value/CSSStringTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

use PHPUnit\Framework\TestCase;
use Sabberworm\CSS\OutputFormat;
use Sabberworm\CSS\Parsing\ParserState;
use Sabberworm\CSS\Settings;
use Sabberworm\CSS\Value\CSSString;
use Sabberworm\CSS\Value\PrimitiveValue;
use Sabberworm\CSS\Value\Value;
Expand Down Expand Up @@ -144,4 +146,18 @@ public function doesNotEscapeDoubleQuotesThatDoNotNeedToBeEscaped(): void

self::assertSame("'{$input}'", (new CSSString($input))->render($outputFormat));
}

/**
* @test
*/
public function parseThrowsForUnquotedStringThatIsNotValidUtf8WithoutMultibyteSupport(): void
{
$parserState = new ParserState("\xFF", Settings::create()->withMultibyteSupport(false));

$this->expectException(\RuntimeException::class);
$this->expectExceptionMessage('The CSS is not valid UTF-8.');
$this->expectExceptionCode(1787548272);

CSSString::parse($parserState);
}
}