Commit 2154edf
fix(lsp/php): prevent OOM when a trait uses itself
flatten_trait_into_class() iterated reg->funcs with a live upper bound
(reg->func_count) while cbm_registry_add_func() appended to that same
array inside the loop. Each copied method is tagged with
receiver_type = class_qn, so when a trait adopts itself -- directly
(`trait T { use T; }`) or via an alias that resolves back to the trait
by short name (`use X\T as A; use A;`) -- class_qn equals
canonical_trait_qn and every appended method re-matches the loop filter,
extending the iteration. The loop never terminates: it arena-allocates a
fresh method each pass until the process exhausts all memory (observed:
40 GB+, freezing the host).
Fix:
- Short-circuit self-flattening: a trait cannot meaningfully use itself
(PHP itself rejects it), so return early when class_qn equals the
resolved trait QN.
- Snapshot reg->func_count before the loop so entries appended during
iteration are never revisited (defensive against the mutate-while-
iterating hazard in general).
Add regression test phplsp_trait_self_use_terminates: it hangs/OOMs on
the pre-fix code and passes after. Verified end to end -- the prod binary
now indexes the triggering file in <0.5s at ~6 MB RSS instead of running
away.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Mubariz <mubariz@sportimport.de>1 parent f092d92 commit 2154edf
2 files changed
Lines changed: 46 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3459 | 3459 | | |
3460 | 3460 | | |
3461 | 3461 | | |
| 3462 | + | |
| 3463 | + | |
| 3464 | + | |
| 3465 | + | |
| 3466 | + | |
| 3467 | + | |
| 3468 | + | |
| 3469 | + | |
| 3470 | + | |
| 3471 | + | |
| 3472 | + | |
| 3473 | + | |
| 3474 | + | |
3462 | 3475 | | |
3463 | 3476 | | |
3464 | 3477 | | |
3465 | 3478 | | |
3466 | 3479 | | |
3467 | | - | |
3468 | | - | |
| 3480 | + | |
| 3481 | + | |
| 3482 | + | |
| 3483 | + | |
| 3484 | + | |
| 3485 | + | |
| 3486 | + | |
3469 | 3487 | | |
3470 | 3488 | | |
3471 | 3489 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
543 | 543 | | |
544 | 544 | | |
545 | 545 | | |
| 546 | + | |
| 547 | + | |
| 548 | + | |
| 549 | + | |
| 550 | + | |
| 551 | + | |
| 552 | + | |
| 553 | + | |
| 554 | + | |
| 555 | + | |
| 556 | + | |
| 557 | + | |
| 558 | + | |
| 559 | + | |
| 560 | + | |
| 561 | + | |
| 562 | + | |
| 563 | + | |
| 564 | + | |
| 565 | + | |
| 566 | + | |
| 567 | + | |
| 568 | + | |
| 569 | + | |
| 570 | + | |
546 | 571 | | |
547 | 572 | | |
548 | 573 | | |
| |||
5160 | 5185 | | |
5161 | 5186 | | |
5162 | 5187 | | |
| 5188 | + | |
5163 | 5189 | | |
5164 | 5190 | | |
5165 | 5191 | | |
| |||
0 commit comments