Skip to content

Require array_search()'s haystack argument before reading it - #6239

Merged
staabm merged 1 commit into
phpstan:2.2.xfrom
SanderMuller:assign-handler-array-search-args
Aug 18, 2026
Merged

Require array_search()'s haystack argument before reading it#6239
staabm merged 1 commit into
phpstan:2.2.xfrom
SanderMuller:assign-handler-array-search-args

Conversation

@SanderMuller

Copy link
Copy Markdown
Contributor

Split out of #6226 as requested in #6226 (comment).

AssignHandler::shouldKeepList() recognizes $list[array_search($needle, $list)] as an offset that keeps an array a list. The branch accepted a call with one argument and then read the second one, so this aborts the analysis on current 2.2.x:

$list = [1, 2, 3];
$list[array_search($list)] = 4;
Internal error: PHPStan\Analyser\ExprHandler\AssignHandler::isSameVariable():
Argument #2 ($b) must be of type PhpParser\Node\Expr, null given,
called in src/Analyser/ExprHandler/AssignHandler.php on line 1916

The haystack is array_search()'s second argument, so requiring two is what the branch already assumed. The call stays malformed - it is now reported as Function array_search invoked with 1 parameter, 2-3 required. instead of ending the run.

A single unpacked argument counts as one argument too, so $list[array_search(...$args)] = 4; reached the same read and is covered as well.

I checked the neighbouring heuristics for the same off-by-one: every other getArgs()[N] in the file is guarded by a count of at least N + 1, and a sweep over src/ for an argument index accessed under a weaker count guard turned up no other case that can be reached (the count() ones bail out on an empty argument list before getting there).

tests/PHPStan/Analyser/nsrt/array-search-offset-argument-count.php holds both cases; with the guard reverted the test errors with the TypeError above. Full suite, self-analysis and phpcs are green.

The list-preserving `$list[array_search($needle, $list)]` heuristic accepted a
call with a single argument and then read the second one, so
`$list[array_search($list)] = 4;` aborted the analysis with

    AssignHandler::isSameVariable(): Argument #2 ($b) must be of type
    PhpParser\Node\Expr, null given

The call is malformed either way; with the argument count checked it is reported
as such instead of ending the run. A single unpacked argument counts as one
argument too and hit the same read.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@staabm staabm left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thank you

@staabm
staabm merged commit 177821d into phpstan:2.2.x Aug 18, 2026
779 of 787 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants