Skip to content

Commit 7b266fc

Browse files
committed
Report maybe invalid string int-offsets
1 parent 3be24b6 commit 7b266fc

File tree

3 files changed

+53
-5
lines changed

3 files changed

+53
-5
lines changed

src/Rules/Arrays/NonexistentOffsetInArrayDimFetchCheck.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use PHPStan\Rules\RuleLevelHelper;
1111
use PHPStan\Type\BenevolentUnionType;
1212
use PHPStan\Type\ErrorType;
13+
use PHPStan\Type\IntegerRangeType;
1314
use PHPStan\Type\Type;
1415
use PHPStan\Type\TypeUtils;
1516
use PHPStan\Type\UnionType;
@@ -65,6 +66,15 @@ public function check(
6566
if ($this->reportMaybes) {
6667
$report = false;
6768

69+
$zeroOrMore = IntegerRangeType::fromInterval(0, null);
70+
if (
71+
$type->isString()->yes()
72+
&& $dimType->isInteger()->yes()
73+
&& !$zeroOrMore->isSuperTypeOf($dimType)->yes()
74+
) {
75+
$report = true;
76+
}
77+
6878
if ($type instanceof BenevolentUnionType) {
6979
$flattenedTypes = [$type];
7080
} else {

tests/PHPStan/Rules/Arrays/NonexistentOffsetInArrayDimFetchRuleTest.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -777,6 +777,26 @@ public function testBug11946(): void
777777
'Offset -1 does not exist on string.',
778778
25,
779779
],
780+
[
781+
'Offset int<-5, 5> might not exist on string.',
782+
45
783+
],
784+
[
785+
'Offset int<-5, 5> might not exist on numeric-string.',
786+
46
787+
],
788+
[
789+
'Offset int<-5, 5> might not exist on non-empty-string.',
790+
47
791+
],
792+
[
793+
'Offset int<-5, 5> might not exist on non-falsy-string.',
794+
48
795+
],
796+
[
797+
'Offset int<-5, 5> might not exist on string.',
798+
49
799+
],
780800
]);
781801
}
782802

tests/PHPStan/Rules/Arrays/data/bug-11946.php

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,29 @@ public function nonExistentStringOffset(
2323
echo $nonEmpty[-1];
2424
echo $nonFalsy[-1];
2525
echo $lowerCase[-1];
26+
}
2627

27-
echo $s[0];
28-
echo $numericS[0];
29-
echo $nonEmpty[0];
30-
echo $nonFalsy[0];
31-
echo $lowerCase[0];
28+
/**
29+
* @param numeric-string $numericS
30+
* @param non-empty-string $nonEmpty
31+
* @param non-falsy-string $nonFalsy
32+
* @param lowercase-string $lowerCase
33+
*
34+
* @param int<-5, 5> $maybeWrong
35+
*/
36+
public function maybeNonExistentStringOffset(
37+
string $s,
38+
string $numericS,
39+
string $nonEmpty,
40+
string $nonFalsy,
41+
string $lowerCase,
42+
int $maybeWrong
43+
)
44+
{
45+
echo $s[$maybeWrong];
46+
echo $numericS[$maybeWrong];
47+
echo $nonEmpty[$maybeWrong];
48+
echo $nonFalsy[$maybeWrong];
49+
echo $lowerCase[$maybeWrong];
3250
}
3351
}

0 commit comments

Comments
 (0)