Skip to content

Commit d310d6b

Browse files
Merge branch 'main' into fix/cypher-coalesce-where-874
2 parents f07d3ad + f7127ee commit d310d6b

1 file changed

Lines changed: 58 additions & 0 deletions

File tree

tests/test_php_lsp.c

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,62 @@ TEST(phplsp_trait_self_use_terminates) {
568568
PASS();
569569
}
570570

571+
/* ── 23c. Regression #765: trait name collides with an aliased import ──
572+
*
573+
* `use Vendor\Pkg\Auditable as AuditableBase;` + `trait Auditable { use
574+
* AuditableBase; ... }` — the composed alias canonicalizes (via short-name
575+
* fallback) onto the ENCLOSING trait itself, which is the same
576+
* self-flattening loop as 23b arriving through the import alias: each
577+
* copied method re-matched the flatten filter while the registry grew,
578+
* OOM-ing the indexer (reported at 40+ GB). Guarded by the #920 pair
579+
* (self-flatten short-circuit + snapshotted loop bound); this fixture is
580+
* the exact reproducer from issue #765 and hung/OOM'd before those. */
581+
TEST(phplsp_trait_aliased_import_name_collision_terminates) {
582+
const char *src = "<?php\n"
583+
"namespace App\\Demo;\n"
584+
"\n"
585+
"use Vendor\\Pkg\\Auditable as AuditableBase;\n"
586+
"\n"
587+
"trait Auditable {\n"
588+
" use AuditableBase;\n"
589+
"\n"
590+
" function f() { $x = 1; return $x; }\n"
591+
"}\n";
592+
CBMFileResult *r = extract_php(src);
593+
ASSERT(r);
594+
cbm_free_result(r);
595+
PASS();
596+
}
597+
598+
/* ── 23d. Regression #951: class shares its short name with an aliased
599+
* trait import ──
600+
*
601+
* `use App\Functions\Delivery as Delivery_Trait;` + `class Delivery { use
602+
* Delivery_Trait; ... }` — resolving the composed alias falls back to the
603+
* short name and lands on the LOCAL CLASS `Delivery`, so the class is
604+
* flattened into itself (class_qn == canonical target QN): the same loop
605+
* as 23b/23c reached through a class/trait short-name collision. Reported
606+
* as an indexer OOM kill (exit 137) in issue #951. The two-file original
607+
* reduces to this single-file form because the trait's definition being
608+
* unavailable is exactly what forces the short-name fallback. */
609+
TEST(phplsp_class_aliased_trait_name_collision_terminates) {
610+
const char *src = "<?php\n"
611+
"namespace App\\Modules\\Foo;\n"
612+
"\n"
613+
"use App\\Functions\\Delivery as Delivery_Trait;\n"
614+
"\n"
615+
"class Delivery {\n"
616+
" use Delivery_Trait;\n"
617+
"\n"
618+
" public function run(): void {\n"
619+
" }\n"
620+
"}\n";
621+
CBMFileResult *r = extract_php(src);
622+
ASSERT(r);
623+
cbm_free_result(r);
624+
PASS();
625+
}
626+
571627
/* ── 24. Match expression result type ──────────────────────────── */
572628

573629
TEST(phplsp_match_result_type) {
@@ -5186,6 +5242,8 @@ SUITE(php_lsp) {
51865242
RUN_TEST(phplsp_phpdoc_method_class_tag);
51875243
RUN_TEST(phplsp_trait_method_flattened);
51885244
RUN_TEST(phplsp_trait_self_use_terminates);
5245+
RUN_TEST(phplsp_trait_aliased_import_name_collision_terminates);
5246+
RUN_TEST(phplsp_class_aliased_trait_name_collision_terminates);
51895247
RUN_TEST(phplsp_match_result_type);
51905248
RUN_TEST(phplsp_ternary_result_type);
51915249
RUN_TEST(phplsp_method_chain_depth_three);

0 commit comments

Comments
 (0)