psalm
psalm copied to clipboard
Preventing use of `false` as an array key
Discussed in https://github.com/vimeo/psalm/discussions/5965
Originally posted by M1ke June 21, 2021 https://psalm.dev/r/b5c9862354
In the given example we are wanting to search for an instance of a string in a list and unset it. However due to PHP's type coercion we accidentally unset the first element in our list instead because array_search
returns false
, and unsetting false
coerces to 0
.
As far as I see Psalm isn't flagging anything here.
I believe Psalm should be able to flag if a potential boolean value is used as an array key as some form of error - bool false is never an appropriate array-key - if somebody wishes to use potential false
as an array key they should type cast it (e.g. 'false'
would be a legitimate array key, as would 0
)
In the class that handles array access, there is a code that will turn everything into integers in order to know what the code will do: https://github.com/vimeo/psalm/blob/19cc4cb4ee962a9872aa1e5c61ab41ef3c4348d5/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/ArrayFetchAnalyzer.php#L1167
We'd need to emit an issue in that method each time the offset is not expected (in this instance, false)
I found these snippets:
https://psalm.dev/r/b5c9862354
<?php
/**
* @return string[]
*/
function returnsList() :array{
return ['a','b','c'];
}
$list = returnsList();
$found_letter = array_search('d', $list);
unset($list[$found_letter]);
Psalm output (using commit cccfe75):
No issues!
I've been bitten by this with a similar case.