Skip to content

Commit 3be24b6

Browse files
committed
Report invalid string offsets
1 parent 8019243 commit 3be24b6

File tree

3 files changed

+61
-1
lines changed

3 files changed

+61
-1
lines changed

src/Type/StringType.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ public function isOffsetAccessLegal(): TrinaryLogic
6363

6464
public function hasOffsetValueType(Type $offsetType): TrinaryLogic
6565
{
66-
return $offsetType->isInteger()->and(TrinaryLogic::createMaybe());
66+
$zeroOrMore = IntegerRangeType::fromInterval(0, null);
67+
return $zeroOrMore->isSuperTypeOf($offsetType)->result->and(TrinaryLogic::createMaybe());
6768
}
6869

6970
public function getOffsetValueType(Type $offsetType): Type

tests/PHPStan/Rules/Arrays/NonexistentOffsetInArrayDimFetchRuleTest.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -754,4 +754,30 @@ public function testBug2634(): void
754754
$this->analyse([__DIR__ . '/data/bug-2634.php'], []);
755755
}
756756

757+
public function testBug11946(): void
758+
{
759+
$this->analyse([__DIR__ . '/data/bug-11946.php'], [
760+
[
761+
'Offset -1 does not exist on string.',
762+
21,
763+
],
764+
[
765+
'Offset -1 does not exist on numeric-string.',
766+
22,
767+
],
768+
[
769+
'Offset -1 does not exist on non-empty-string.',
770+
23,
771+
],
772+
[
773+
'Offset -1 does not exist on non-falsy-string.',
774+
24,
775+
],
776+
[
777+
'Offset -1 does not exist on string.',
778+
25,
779+
],
780+
]);
781+
}
782+
757783
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Bug11946;
4+
5+
class HelloWorld
6+
{
7+
/**
8+
* @param numeric-string $numericS
9+
* @param non-empty-string $nonEmpty
10+
* @param non-falsy-string $nonFalsy
11+
* @param lowercase-string $lowerCase
12+
*/
13+
public function nonExistentStringOffset(
14+
string $s,
15+
string $numericS,
16+
string $nonEmpty,
17+
string $nonFalsy,
18+
string $lowerCase,
19+
)
20+
{
21+
echo $s[-1];
22+
echo $numericS[-1];
23+
echo $nonEmpty[-1];
24+
echo $nonFalsy[-1];
25+
echo $lowerCase[-1];
26+
27+
echo $s[0];
28+
echo $numericS[0];
29+
echo $nonEmpty[0];
30+
echo $nonFalsy[0];
31+
echo $lowerCase[0];
32+
}
33+
}

0 commit comments

Comments
 (0)