1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-30 04:39:00 +01:00

Prevent illegal array keys (#4660)

* Emit an issue when an array-key is not legal

* tests
This commit is contained in:
orklah 2020-11-23 21:20:39 +01:00 committed by Daniil Gentili
parent fe4423de78
commit 597b7aa064
Signed by: danog
GPG Key ID: 8C1BE3B34B230CA7
2 changed files with 59 additions and 2 deletions

View File

@ -7,6 +7,7 @@ use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\Issue\DuplicateArrayKey;
use Psalm\Issue\InvalidArrayOffset;
use Psalm\IssueBuffer;
use Psalm\Type;
use Psalm\Internal\Type\TypeCombiner;
@ -356,6 +357,30 @@ class ArrayAnalyzer
return true;
}
if ($item_key_type) {
foreach ($item_key_type->getAtomicTypes() as $atomic_key_type) {
if (!$atomic_key_type instanceof Type\Atomic\TString &&
!$atomic_key_type instanceof Type\Atomic\TInt &&
!$atomic_key_type instanceof Type\Atomic\TArrayKey &&
!$atomic_key_type instanceof Type\Atomic\TMixed &&
!(
$atomic_key_type instanceof Type\Atomic\TObjectWithProperties &&
isset($atomic_key_type->methods['__toString'])
)
) {
if (IssueBuffer::accepts(
new InvalidArrayOffset(
'Cannot create offset of type ' . $item_key_type->getKey() . ', expecting array-key',
new CodeLocation($statements_analyzer->getSource(), $stmt)
),
$statements_analyzer->getSuppressedIssues()
)) {
$item_key_type = Type::getArrayKey();
}
}
}
}
$array_type = new Type\Atomic\TNonEmptyArray([
$item_key_type && !$item_key_type->hasMixed() ? $item_key_type : Type::getArrayKey(),
$item_value_type ?: Type::getMixed(),

View File

@ -2,6 +2,7 @@
namespace Psalm\Tests;
use Psalm\Context;
use Psalm\Issue\InvalidArrayOffset;
class ArrayAssignmentTest extends TestCase
{
@ -1548,7 +1549,20 @@ class ArrayAssignmentTest extends TestCase
{
return [...$data];
}'
]
],
'ArrayCreateOffsetStringable' => [
'<?php
$a = new class{public function __toString(){return "";}};
$_a = [$a => "a"];
',
],
'ArrayCreateOffsetMixed' => [
'<?php
/** @var mixed $b */
$b = "";
$_a = [$b => "a"];
',
],
];
}
@ -1851,7 +1865,25 @@ class ArrayAssignmentTest extends TestCase
return [...$data];
}',
'error_message' => 'DuplicateArrayKey'
]
],
'ArrayCreateOffsetObject' => [
'<?php
$_a = [new stdClass => "a"];
',
'error_message' => 'InvalidArrayOffset'
],
'ArrayCreateOffsetResource' => [
'<?php
$_a = [fopen("", "") => "a"];
',
'error_message' => 'InvalidArrayOffset'
],
'ArrayCreateOffsetBool' => [
'<?php
$_a = [true => "a"];
',
'error_message' => 'InvalidArrayOffset'
],
];
}
}