Skip to content

Commit a95dd4a

Browse files
authored
Fix key type of superglobal variables
1 parent 4cc79ef commit a95dd4a

File tree

8 files changed

+149
-5
lines changed

8 files changed

+149
-5
lines changed

src/Analyser/MutatingScope.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
use PHPStan\Type\Accessory\NonEmptyArrayType;
7272
use PHPStan\Type\Accessory\OversizedArrayType;
7373
use PHPStan\Type\ArrayType;
74+
use PHPStan\Type\BenevolentUnionType;
7475
use PHPStan\Type\BooleanType;
7576
use PHPStan\Type\ClosureType;
7677
use PHPStan\Type\Constant\ConstantArrayTypeBuilder;
@@ -507,7 +508,7 @@ public function getVariableType(string $variableName): Type
507508
}
508509

509510
if ($this->isGlobalVariable($variableName)) {
510-
return new ArrayType(new StringType(), new MixedType($this->explicitMixedForGlobalVariables));
511+
return new ArrayType(new BenevolentUnionType([new IntegerType(), new StringType()]), new MixedType($this->explicitMixedForGlobalVariables));
511512
}
512513

513514
if ($this->hasVariableType($variableName)->no()) {

tests/PHPStan/Analyser/NodeScopeResolverTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1257,6 +1257,7 @@ public function dataFileAsserts(): iterable
12571257
yield from $this->gatherAssertTypes(__DIR__ . '/data/image-size.php');
12581258
yield from $this->gatherAssertTypes(__DIR__ . '/data/base64_decode.php');
12591259
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-9404.php');
1260+
yield from $this->gatherAssertTypes(__DIR__ . '/data/globals.php');
12601261
}
12611262

12621263
/**

tests/PHPStan/Analyser/data/filter-var-array.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -198,11 +198,11 @@ function superGlobalVariables(): void
198198
], false));
199199

200200
// filter flag with add_empty=default
201-
assertType('array<string, int|false>', filter_var_array($_POST, FILTER_VALIDATE_INT));
201+
assertType('array<int|false>', filter_var_array($_POST, FILTER_VALIDATE_INT));
202202
// filter flag with add_empty=true
203-
assertType('array<string, int|false>', filter_var_array($_POST, FILTER_VALIDATE_INT, true));
203+
assertType('array<int|false>', filter_var_array($_POST, FILTER_VALIDATE_INT, true));
204204
// filter flag with add_empty=false
205-
assertType('array<string, int|false>', filter_var_array($_POST, FILTER_VALIDATE_INT, false));
205+
assertType('array<int|false>', filter_var_array($_POST, FILTER_VALIDATE_INT, false));
206206
}
207207

208208
/**
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
\PHPStan\Testing\assertType('array', $GLOBALS);
4+
\PHPStan\Testing\assertType('array', $_SERVER);
5+
\PHPStan\Testing\assertType('array', $_GET);
6+
\PHPStan\Testing\assertType('array', $_POST);
7+
\PHPStan\Testing\assertType('array', $_FILES);
8+
\PHPStan\Testing\assertType('array', $_COOKIE);
9+
\PHPStan\Testing\assertType('array', $_SESSION);
10+
\PHPStan\Testing\assertType('array', $_REQUEST);
11+
\PHPStan\Testing\assertType('array', $_ENV);

tests/PHPStan/Rules/Comparison/data/check-type-function-call.php

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -928,3 +928,42 @@ public function doFoo(int $i, string $s, array $nonEmptyInts, array $strings): v
928928
}
929929
}
930930
}
931+
932+
function checkSuperGlobals(): void
933+
{
934+
foreach ($GLOBALS as $k => $v) {
935+
if (is_int($k)) {}
936+
}
937+
938+
foreach ($_SERVER as $k => $v) {
939+
if (is_int($k)) {}
940+
}
941+
942+
foreach ($_GET as $k => $v) {
943+
if (is_int($k)) {}
944+
}
945+
946+
foreach ($_POST as $k => $v) {
947+
if (is_int($k)) {}
948+
}
949+
950+
foreach ($_FILES as $k => $v) {
951+
if (is_int($k)) {}
952+
}
953+
954+
foreach ($_COOKIE as $k => $v) {
955+
if (is_int($k)) {}
956+
}
957+
958+
foreach ($_SESSION as $k => $v) {
959+
if (is_int($k)) {}
960+
}
961+
962+
foreach ($_REQUEST as $k => $v) {
963+
if (is_int($k)) {}
964+
}
965+
966+
foreach ($_ENV as $k => $v) {
967+
if (is_int($k)) {}
968+
}
969+
}

tests/PHPStan/Rules/Functions/CallToFunctionParametersRuleTest.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1358,4 +1358,9 @@ public function testBug9380(): void
13581358
$this->analyse([__DIR__ . '/data/bug-9380.php'], $errors);
13591359
}
13601360

1361+
public function testBenevolentSuperglobalKeys(): void
1362+
{
1363+
$this->analyse([__DIR__ . '/data/benevolent-superglobal-keys.php'], []);
1364+
}
1365+
13611366
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace CallFunctionsBenevolentSuperglobalKeys;
6+
7+
function benevolentKeysOfSuperglobalsString(): void
8+
{
9+
foreach ($GLOBALS as $k => $v) {
10+
trim($k);
11+
}
12+
13+
foreach ($_SERVER as $k => $v) {
14+
trim($k);
15+
}
16+
17+
foreach ($_GET as $k => $v) {
18+
trim($k);
19+
}
20+
21+
foreach ($_POST as $k => $v) {
22+
trim($k);
23+
}
24+
25+
foreach ($_FILES as $k => $v) {
26+
trim($k);
27+
}
28+
29+
foreach ($_COOKIE as $k => $v) {
30+
trim($k);
31+
}
32+
33+
foreach ($_SESSION as $k => $v) {
34+
trim($k);
35+
}
36+
37+
foreach ($_REQUEST as $k => $v) {
38+
trim($k);
39+
}
40+
41+
foreach ($_ENV as $k => $v) {
42+
trim($k);
43+
}
44+
}
45+
46+
function benevolentKeysOfSuperglobalsInt(): void
47+
{
48+
foreach ($GLOBALS as $k => $v) {
49+
acceptInt($k);
50+
}
51+
52+
foreach ($_SERVER as $k => $v) {
53+
acceptInt($k);
54+
}
55+
56+
foreach ($_GET as $k => $v) {
57+
acceptInt($k);
58+
}
59+
60+
foreach ($_POST as $k => $v) {
61+
acceptInt($k);
62+
}
63+
64+
foreach ($_FILES as $k => $v) {
65+
acceptInt($k);
66+
}
67+
68+
foreach ($_COOKIE as $k => $v) {
69+
acceptInt($k);
70+
}
71+
72+
foreach ($_SESSION as $k => $v) {
73+
acceptInt($k);
74+
}
75+
76+
foreach ($_REQUEST as $k => $v) {
77+
acceptInt($k);
78+
}
79+
80+
foreach ($_ENV as $k => $v) {
81+
acceptInt($k);
82+
}
83+
}
84+
85+
function acceptInt(int $i): void
86+
{
87+
}

tests/PHPStan/Rules/Methods/CallMethodsRuleTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2209,7 +2209,7 @@ public function testLiteralString(): void
22092209
60,
22102210
],
22112211
[
2212-
'Parameter #1 $s of method LiteralStringMethod\Foo::requireLiteralString() expects literal-string, array<string, mixed> given.',
2212+
'Parameter #1 $s of method LiteralStringMethod\Foo::requireLiteralString() expects literal-string, array given.',
22132213
65,
22142214
],
22152215
[

0 commit comments

Comments
 (0)