Skip to content

Commit f178eeb

Browse files
committed
Report invalid string offsets
1 parent c5df243 commit f178eeb

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
@@ -780,4 +780,30 @@ public function testInternalClassesWithOverloadedOffsetAccessInvalid84(): void
780780
$this->analyse([__DIR__ . '/data/internal-classes-overload-offset-access-invalid-php84.php'], []);
781781
}
782782

783+
public function testBug11946(): void
784+
{
785+
$this->analyse([__DIR__ . '/data/bug-11946.php'], [
786+
[
787+
'Offset -1 does not exist on string.',
788+
21,
789+
],
790+
[
791+
'Offset -1 does not exist on numeric-string.',
792+
22,
793+
],
794+
[
795+
'Offset -1 does not exist on non-empty-string.',
796+
23,
797+
],
798+
[
799+
'Offset -1 does not exist on non-falsy-string.',
800+
24,
801+
],
802+
[
803+
'Offset -1 does not exist on string.',
804+
25,
805+
],
806+
]);
807+
}
808+
783809
}
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)