mirror of
https://github.com/danog/psalm.git
synced 2024-12-02 09:37:59 +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\CodeLocation;
|
||||||
use Psalm\Context;
|
use Psalm\Context;
|
||||||
use Psalm\Issue\DuplicateArrayKey;
|
use Psalm\Issue\DuplicateArrayKey;
|
||||||
|
use Psalm\Issue\InvalidArrayOffset;
|
||||||
use Psalm\IssueBuffer;
|
use Psalm\IssueBuffer;
|
||||||
use Psalm\Type;
|
use Psalm\Type;
|
||||||
use Psalm\Internal\Type\TypeCombiner;
|
use Psalm\Internal\Type\TypeCombiner;
|
||||||
@ -356,6 +357,30 @@ class ArrayAnalyzer
|
|||||||
return true;
|
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([
|
$array_type = new Type\Atomic\TNonEmptyArray([
|
||||||
$item_key_type && !$item_key_type->hasMixed() ? $item_key_type : Type::getArrayKey(),
|
$item_key_type && !$item_key_type->hasMixed() ? $item_key_type : Type::getArrayKey(),
|
||||||
$item_value_type ?: Type::getMixed(),
|
$item_value_type ?: Type::getMixed(),
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
namespace Psalm\Tests;
|
namespace Psalm\Tests;
|
||||||
|
|
||||||
use Psalm\Context;
|
use Psalm\Context;
|
||||||
|
use Psalm\Issue\InvalidArrayOffset;
|
||||||
|
|
||||||
class ArrayAssignmentTest extends TestCase
|
class ArrayAssignmentTest extends TestCase
|
||||||
{
|
{
|
||||||
@ -1548,7 +1549,20 @@ class ArrayAssignmentTest extends TestCase
|
|||||||
{
|
{
|
||||||
return [...$data];
|
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];
|
return [...$data];
|
||||||
}',
|
}',
|
||||||
'error_message' => 'DuplicateArrayKey'
|
'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