From f71c1c493e783a964aeeab78033f2d13a02b38a7 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Mon, 3 Mar 2025 12:26:06 +0100 Subject: [PATCH 1/2] Make missing trait error recoverable We were already handling NULL as a case, but seem to have forgotten to pass the ZEND_FETCH_CLASS_EXCEPTION flag. Fixes GH-17959 --- Zend/tests/traits/bugs/missing-trait.phpt | 5 ++++- Zend/tests/traits/error_002.phpt | 5 ++++- Zend/tests/traits/gh17959.phpt | 18 ++++++++++++++++++ Zend/zend_inheritance.c | 2 +- 4 files changed, 27 insertions(+), 3 deletions(-) create mode 100644 Zend/tests/traits/gh17959.phpt diff --git a/Zend/tests/traits/bugs/missing-trait.phpt b/Zend/tests/traits/bugs/missing-trait.phpt index 4bf054e88900..0b36c47e771d 100644 --- a/Zend/tests/traits/bugs/missing-trait.phpt +++ b/Zend/tests/traits/bugs/missing-trait.phpt @@ -12,4 +12,7 @@ $test = new TraitsTest(); ?> --EXPECTF-- -Fatal error: Trait "THello" not found in %s on line %d +Fatal error: Uncaught Error: Trait "THello" not found in %s:%d +Stack trace: +#0 {main} + thrown in %s on line %d diff --git a/Zend/tests/traits/error_002.phpt b/Zend/tests/traits/error_002.phpt index 53ad403a4337..fc9cfc5884c4 100644 --- a/Zend/tests/traits/error_002.phpt +++ b/Zend/tests/traits/error_002.phpt @@ -9,4 +9,7 @@ class A { ?> --EXPECTF-- -Fatal error: Trait "abc" not found in %s on line %d +Fatal error: Uncaught Error: Trait "abc" not found in %s:%d +Stack trace: +#0 {main} + thrown in %s on line %d diff --git a/Zend/tests/traits/gh17959.phpt b/Zend/tests/traits/gh17959.phpt new file mode 100644 index 000000000000..016dd7a4a4f7 --- /dev/null +++ b/Zend/tests/traits/gh17959.phpt @@ -0,0 +1,18 @@ +--TEST-- +GH-17959: Missing trait error is recoverable +--FILE-- +getMessage(), "\n"; +} + +?> +===DONE=== +--EXPECT-- +Error: Trait "MissingTrait" not found +===DONE=== diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index f5496514fcb7..3c3e62361381 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -3535,7 +3535,7 @@ ZEND_API zend_class_entry *zend_do_link_class(zend_class_entry *ce, zend_string for (i = 0; i < ce->num_traits; i++) { zend_class_entry *trait = zend_fetch_class_by_name(ce->trait_names[i].name, - ce->trait_names[i].lc_name, ZEND_FETCH_CLASS_TRAIT); + ce->trait_names[i].lc_name, ZEND_FETCH_CLASS_TRAIT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(trait == NULL)) { free_alloca(traits_and_interfaces, use_heap); return NULL; From 56e041200607eaa416350eb4967f8fae4554144a Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Mon, 10 Mar 2025 14:12:28 +0100 Subject: [PATCH 2/2] Also relax "is not a trait" error --- Zend/tests/traits/error_003.phpt | 5 ++++- Zend/tests/traits/error_004.phpt | 5 ++++- Zend/tests/traits/error_005.phpt | 5 ++++- Zend/tests/traits/error_006.phpt | 5 ++++- Zend/zend_inheritance.c | 2 +- 5 files changed, 17 insertions(+), 5 deletions(-) diff --git a/Zend/tests/traits/error_003.phpt b/Zend/tests/traits/error_003.phpt index fdfa0ac1fe22..6a6d2d56d6c4 100644 --- a/Zend/tests/traits/error_003.phpt +++ b/Zend/tests/traits/error_003.phpt @@ -12,4 +12,7 @@ class A { ?> --EXPECTF-- -Fatal error: A cannot use abc - it is not a trait in %s on line %d +Fatal error: Uncaught Error: A cannot use abc - it is not a trait in %s:%d +Stack trace: +#0 {main} + thrown in %s on line %d diff --git a/Zend/tests/traits/error_004.phpt b/Zend/tests/traits/error_004.phpt index d7ff695e047b..1e339f3d6314 100644 --- a/Zend/tests/traits/error_004.phpt +++ b/Zend/tests/traits/error_004.phpt @@ -12,4 +12,7 @@ class A { ?> --EXPECTF-- -Fatal error: A cannot use abc - it is not a trait in %s on line %d +Fatal error: Uncaught Error: A cannot use abc - it is not a trait in %s:%d +Stack trace: +#0 {main} + thrown in %s on line %d diff --git a/Zend/tests/traits/error_005.phpt b/Zend/tests/traits/error_005.phpt index 3b8cc32f9758..dae8e1893a68 100644 --- a/Zend/tests/traits/error_005.phpt +++ b/Zend/tests/traits/error_005.phpt @@ -12,4 +12,7 @@ class A { ?> --EXPECTF-- -Fatal error: A cannot use abc - it is not a trait in %s on line %d +Fatal error: Uncaught Error: A cannot use abc - it is not a trait in %s:%d +Stack trace: +#0 {main} + thrown in %s on line %d diff --git a/Zend/tests/traits/error_006.phpt b/Zend/tests/traits/error_006.phpt index f3ed87123cf2..5d831a9da7f1 100644 --- a/Zend/tests/traits/error_006.phpt +++ b/Zend/tests/traits/error_006.phpt @@ -12,4 +12,7 @@ class A { ?> --EXPECTF-- -Fatal error: A cannot use abc - it is not a trait in %s on line %d +Fatal error: Uncaught Error: A cannot use abc - it is not a trait in %s:%d +Stack trace: +#0 {main} + thrown in %s on line %d diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index 3c3e62361381..170da095f901 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -3541,7 +3541,7 @@ ZEND_API zend_class_entry *zend_do_link_class(zend_class_entry *ce, zend_string return NULL; } if (UNEXPECTED(!(trait->ce_flags & ZEND_ACC_TRAIT))) { - zend_error_noreturn(E_ERROR, "%s cannot use %s - it is not a trait", ZSTR_VAL(ce->name), ZSTR_VAL(trait->name)); + zend_throw_error(NULL, "%s cannot use %s - it is not a trait", ZSTR_VAL(ce->name), ZSTR_VAL(trait->name)); free_alloca(traits_and_interfaces, use_heap); return NULL; }