Skip to content

Commit 8731c95

Browse files
committed
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. Also make "is not a trait" error recoverable, there's no reason why it can't be. Fixes GH-17959 Closes GH-17960
1 parent 0a811ce commit 8731c95

9 files changed

+46
-8
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ PHP NEWS
2727
. Fixed bug GH-17442 (Engine UAF with reference assign and dtor). (nielsdos)
2828
. Improved error message of UnhandledMatchError for
2929
zend.exception_string_param_max_len=0. (timwolla)
30+
. Fixed bug GH-17959 (Relax missing trait fatal error to error exception).
31+
(ilutov)
3032

3133
- Curl:
3234
. Added curl_multi_get_handles(). (timwolla)

Zend/tests/traits/bugs/missing-trait.phpt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,7 @@ $test = new TraitsTest();
1212

1313
?>
1414
--EXPECTF--
15-
Fatal error: Trait "THello" not found in %s on line %d
15+
Fatal error: Uncaught Error: Trait "THello" not found in %s:%d
16+
Stack trace:
17+
#0 {main}
18+
thrown in %s on line %d

Zend/tests/traits/error_002.phpt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,7 @@ class A {
99

1010
?>
1111
--EXPECTF--
12-
Fatal error: Trait "abc" not found in %s on line %d
12+
Fatal error: Uncaught Error: Trait "abc" not found in %s:%d
13+
Stack trace:
14+
#0 {main}
15+
thrown in %s on line %d

Zend/tests/traits/error_003.phpt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,7 @@ class A {
1212

1313
?>
1414
--EXPECTF--
15-
Fatal error: A cannot use abc - it is not a trait in %s on line %d
15+
Fatal error: Uncaught Error: A cannot use abc - it is not a trait in %s:%d
16+
Stack trace:
17+
#0 {main}
18+
thrown in %s on line %d

Zend/tests/traits/error_004.phpt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,7 @@ class A {
1212

1313
?>
1414
--EXPECTF--
15-
Fatal error: A cannot use abc - it is not a trait in %s on line %d
15+
Fatal error: Uncaught Error: A cannot use abc - it is not a trait in %s:%d
16+
Stack trace:
17+
#0 {main}
18+
thrown in %s on line %d

Zend/tests/traits/error_005.phpt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,7 @@ class A {
1212

1313
?>
1414
--EXPECTF--
15-
Fatal error: A cannot use abc - it is not a trait in %s on line %d
15+
Fatal error: Uncaught Error: A cannot use abc - it is not a trait in %s:%d
16+
Stack trace:
17+
#0 {main}
18+
thrown in %s on line %d

Zend/tests/traits/error_006.phpt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,7 @@ class A {
1212

1313
?>
1414
--EXPECTF--
15-
Fatal error: A cannot use abc - it is not a trait in %s on line %d
15+
Fatal error: Uncaught Error: A cannot use abc - it is not a trait in %s:%d
16+
Stack trace:
17+
#0 {main}
18+
thrown in %s on line %d

Zend/tests/traits/gh17959.phpt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
--TEST--
2+
GH-17959: Missing trait error is recoverable
3+
--FILE--
4+
<?php
5+
6+
try {
7+
class C {
8+
use MissingTrait;
9+
}
10+
} catch (Error $e) {
11+
echo $e::class, ': ', $e->getMessage(), "\n";
12+
}
13+
14+
?>
15+
===DONE===
16+
--EXPECT--
17+
Error: Trait "MissingTrait" not found
18+
===DONE===

Zend/zend_inheritance.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3546,13 +3546,13 @@ ZEND_API zend_class_entry *zend_do_link_class(zend_class_entry *ce, zend_string
35463546

35473547
for (i = 0; i < ce->num_traits; i++) {
35483548
zend_class_entry *trait = zend_fetch_class_by_name(ce->trait_names[i].name,
3549-
ce->trait_names[i].lc_name, ZEND_FETCH_CLASS_TRAIT);
3549+
ce->trait_names[i].lc_name, ZEND_FETCH_CLASS_TRAIT | ZEND_FETCH_CLASS_EXCEPTION);
35503550
if (UNEXPECTED(trait == NULL)) {
35513551
free_alloca(traits_and_interfaces, use_heap);
35523552
return NULL;
35533553
}
35543554
if (UNEXPECTED(!(trait->ce_flags & ZEND_ACC_TRAIT))) {
3555-
zend_error_noreturn(E_ERROR, "%s cannot use %s - it is not a trait", ZSTR_VAL(ce->name), ZSTR_VAL(trait->name));
3555+
zend_throw_error(NULL, "%s cannot use %s - it is not a trait", ZSTR_VAL(ce->name), ZSTR_VAL(trait->name));
35563556
free_alloca(traits_and_interfaces, use_heap);
35573557
return NULL;
35583558
}

0 commit comments

Comments
 (0)