Skip to content

Commit

Permalink
RegularExpressionPatternRule: fix false positive in preg_quote() hand…
Browse files Browse the repository at this point in the history
…ling
  • Loading branch information
staabm authored and ondrejmirtes committed Aug 2, 2024
1 parent a2a0a51 commit 164691d
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 13 deletions.
6 changes: 5 additions & 1 deletion src/Type/Php/RegexExpressionHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,16 @@ public function __construct(private Scope $scope)

public function resolve(Expr $expr): Type
{
// assume preg_quote() cannot create capturing groups or contain meta characters.
// replace it with a pattern which matches anything, does not affect $matches results
// and does not produce regex errors when followed by a quantifier.
// this allows us to turn string concatenations with preg_quote() into static analyzable strings.
if (
$expr instanceof Expr\FuncCall
&& $expr->name instanceof Name
&& $expr->name->toLowerString() === 'preg_quote'
) {
return new ConstantStringType('.*');
return new ConstantStringType('(?:.*)');
}

if ($expr instanceof Concat) {
Expand Down
24 changes: 12 additions & 12 deletions tests/PHPStan/Rules/Regexp/RegularExpressionPatternRuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -119,27 +119,27 @@ public function testValidRegexPatternBefore73(): void
43,
],
[
'Regex pattern is invalid: Delimiter must not be alphanumeric or backslash in pattern: nok.*',
'Regex pattern is invalid: Delimiter must not be alphanumeric or backslash in pattern: nok(?:.*)',
57,
],
[
'Regex pattern is invalid: Delimiter must not be alphanumeric or backslash in pattern: nok.*',
'Regex pattern is invalid: Delimiter must not be alphanumeric or backslash in pattern: nok(?:.*)',
58,
],
[
'Regex pattern is invalid: Compilation failed: missing ) at offset 3 in pattern: ~(.*~',
'Regex pattern is invalid: Compilation failed: missing ) at offset 7 in pattern: ~((?:.*)~',
59,
],
[
'Regex pattern is invalid: Delimiter must not be alphanumeric or backslash in pattern: nok.*nono',
'Regex pattern is invalid: Delimiter must not be alphanumeric or backslash in pattern: nok(?:.*)nono',
61,
],
[
'Regex pattern is invalid: Delimiter must not be alphanumeric or backslash in pattern: nok.*nope',
'Regex pattern is invalid: Delimiter must not be alphanumeric or backslash in pattern: nok(?:.*)nope',
62,
],
[
'Regex pattern is invalid: Compilation failed: missing ) at offset 3 in pattern: ~(.*~',
'Regex pattern is invalid: Compilation failed: missing ) at offset 7 in pattern: ~((?:.*)~',
63,
],
],
Expand Down Expand Up @@ -249,27 +249,27 @@ public function testValidRegexPatternAfter73(): void
43,
],
[
sprintf('Regex pattern is invalid: Delimiter must not be %s in pattern: nok.*', $messagePart),
sprintf('Regex pattern is invalid: Delimiter must not be %s in pattern: nok(?:.*)', $messagePart),
57,
],
[
sprintf('Regex pattern is invalid: Delimiter must not be %s in pattern: nok.*', $messagePart),
sprintf('Regex pattern is invalid: Delimiter must not be %s in pattern: nok(?:.*)', $messagePart),
58,
],
[
'Regex pattern is invalid: Compilation failed: missing closing parenthesis at offset 3 in pattern: ~(.*~',
'Regex pattern is invalid: Compilation failed: missing closing parenthesis at offset 7 in pattern: ~((?:.*)~',
59,
],
[
sprintf('Regex pattern is invalid: Delimiter must not be %s in pattern: nok.*nono', $messagePart),
sprintf('Regex pattern is invalid: Delimiter must not be %s in pattern: nok(?:.*)nono', $messagePart),
61,
],
[
sprintf('Regex pattern is invalid: Delimiter must not be %s in pattern: nok.*nope', $messagePart),
sprintf('Regex pattern is invalid: Delimiter must not be %s in pattern: nok(?:.*)nope', $messagePart),
62,
],
[
'Regex pattern is invalid: Compilation failed: missing closing parenthesis at offset 3 in pattern: ~(.*~',
'Regex pattern is invalid: Compilation failed: missing closing parenthesis at offset 7 in pattern: ~((?:.*)~',
63,
],
],
Expand Down
21 changes: 21 additions & 0 deletions tests/PHPStan/Rules/Regexp/data/valid-regex-pattern.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,24 @@ public function sayHello(string $s): void
preg_replace('![' . preg_quote($s) . ']+!u', $s, $s);
}
}

class Bug11432 {
function a(string $str, string $character = ',', bool $trim = false): string
{
$str = preg_replace('#' . preg_quote($character, '#') . '{2,}#', $character, $str);

return ($trim) ? trim($str, $character) : $str;
}
function b(string $str, string $character = ',', bool $trim = false): string
{
$str = preg_replace('#' . preg_quote($character, '#') . '*#', $character, $str);

return ($trim) ? trim($str, $character) : $str;
}
function c(string $str, string $character = ',', bool $trim = false): string
{
$str = preg_replace('#' . preg_quote($character, '#') . '?#', $character, $str);

return ($trim) ? trim($str, $character) : $str;
}
}

0 comments on commit 164691d

Please sign in to comment.