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:
parent
fe4423de78
commit
597b7aa064
@ -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(),
|
||||
|
@ -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'
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user