Skip to content

Commit

Permalink
Narrow the type of haystack when strpos != false
Browse files Browse the repository at this point in the history
  • Loading branch information
robchett committed May 21, 2023
1 parent 5370492 commit bd0ba6e
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 9 deletions.
17 changes: 14 additions & 3 deletions stubs/CoreGenericFunctions.phpstub
Original file line number Diff line number Diff line change
Expand Up @@ -627,12 +627,23 @@ function substr_replace($string, $replace, $offset, $length = null) {}

/**
* @psalm-pure
*
* @param string $haystack
*
* @param string $needle
* @param int $offset
* @psalm-assert-if-true =non-empty-string $haystack
* @psalm-return positive-int|0|false
*/
function strpos(string $haystack, string $needle, int $offset = 0) {}

/**
* @psalm-pure
* @param string $haystack
* @param string $needle
* @param int $offset
* @psalm-assert-if-true =non-empty-string $haystack
* @psalm-return positive-int|0|false
*/
function strpos($haystack, $needle, int $offset = 0) : int|false {}
function stripos(string $haystack, string $needle, int $offset = 0) {}

/**
* @psalm-pure
Expand Down
25 changes: 25 additions & 0 deletions tests/CoreStubsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -211,14 +211,39 @@ function after_str_ends_with(): string
}
throw new RuntimeException();
}
/** @return non-empty-string */
function after_strpos(): string
{
$string = uniqid();
if (strpos($string, "foo") !== false) {
return $string;
}
throw new RuntimeException();
}
/** @return non-empty-string */
function after_stripos(): string
{
$string = uniqid();
if (stripos($string, "foo") !== false) {
return $string;
}
throw new RuntimeException();
}
$a = after_str_contains();
$b = after_str_starts_with();
$c = after_str_ends_with();
$d = after_strpos();
$e = after_stripos();
',
'assertions' => [
'$a===' => 'non-empty-string',
'$b===' => 'non-empty-string',
'$c===' => 'non-empty-string',
'$d===' => 'non-empty-string',
'$e===' => 'non-empty-string',
],
];
yield "PHP8 str_* function doesn't subtract string after assertion" => [
Expand Down
13 changes: 7 additions & 6 deletions tests/FunctionCallTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -598,12 +598,6 @@ function foo(string $a, string $b) : int {
return $aTime - $bTime;
}',
],
'strposIntSecondParam' => [
'code' => '<?php
function hasZeroByteOffset(string $s) : bool {
return strpos($s, 0) !== false;
}',
],
'functionCallInGlobalScope' => [
'code' => '<?php
$a = function() use ($argv) : void {};',
Expand Down Expand Up @@ -3019,6 +3013,13 @@ function foo(callable $_a = "strlen"): void {}
',
'error_message' => 'InvalidParamDefault',
],
'disallowStrposIntSecondParam' => [
'code' => '<?php
function hasZeroByteOffset(string $s) : bool {
return strpos($s, 0) !== false;
}',
'error_message' => 'InvalidScalarArgument',
],
];
}

Expand Down

0 comments on commit bd0ba6e

Please sign in to comment.