Skip to content

Commit d78c3df

Browse files
committed
Mark preg_filter() as @pure-unless-parameter-passed
preg_filter() has the same signature as the already-covered preg_replace() (a pure regex substitution with an optional by-ref $count out-parameter), so it stays pure unless $count is passed.
1 parent 850d542 commit d78c3df

4 files changed

Lines changed: 26 additions & 0 deletions

File tree

‎bin/functionMetadata_original.php‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,7 @@
268268
'output_reset_rewrite_vars' => ['hasSideEffects' => true],
269269
'pclose' => ['hasSideEffects' => true],
270270
'popen' => ['hasSideEffects' => true],
271+
'preg_filter' => ['pureUnlessParameterPassedParameters' => ['count' => true]],
271272
// 'matches'/'subpatterns': PHP 8+ uses the php-8-stubs parameter name, PHP <8 falls
272273
// back to the legacy functionMap.php name.
273274
'preg_match' => ['pureUnlessParameterPassedParameters' => ['matches' => true, 'subpatterns' => true]],

‎resources/functionMetadata.php‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1634,6 +1634,7 @@
16341634
'posix_ttyname' => ['hasSideEffects' => false],
16351635
'posix_uname' => ['hasSideEffects' => false],
16361636
'pow' => ['hasSideEffects' => false],
1637+
'preg_filter' => ['pureUnlessParameterPassedParameters' => ['count' => true]],
16371638
'preg_grep' => ['hasSideEffects' => false],
16381639
'preg_last_error' => ['hasSideEffects' => true],
16391640
'preg_last_error_msg' => ['hasSideEffects' => true],

‎tests/PHPStan/Rules/Pure/PureFunctionRuleTest.php‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,10 @@ public function testPureUnlessParameterPassedBuiltin(): void
456456
'Impure call to function preg_match() in pure function PureUnlessParameterPassedBuiltin\purePregMatchWithMatches().',
457457
40,
458458
],
459+
[
460+
'Impure call to function preg_filter() in pure function PureUnlessParameterPassedBuiltin\purePregFilterWithCount().',
461+
60,
462+
],
459463
]);
460464
}
461465

‎tests/PHPStan/Rules/Pure/data/pure-unless-parameter-passed-builtin.php‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,23 @@ function purePregMatchWithMatches(string $s): int
3939
// The by-ref $matches is passed, so preg_match() is impure (the flag is certain).
4040
return (int) preg_match('/a/', $s, $matches);
4141
}
42+
43+
/**
44+
* @phpstan-pure
45+
*/
46+
function purePregFilterWithoutCount(string $s): ?string
47+
{
48+
// The by-ref $count is omitted, so preg_filter() is pure.
49+
return preg_filter('/a/', 'b', $s);
50+
}
51+
52+
/**
53+
* @phpstan-pure
54+
*/
55+
function purePregFilterWithCount(string $s): ?string
56+
{
57+
// The by-ref $count is passed, so preg_filter() is impure (the flag is certain).
58+
$count = 0;
59+
60+
return preg_filter('/a/', 'b', $s, -1, $count);
61+
}

0 commit comments

Comments
 (0)