Skip to content

Commit c8fa477

Browse files
committed
Convert exception during delayed autoload to fatal error
Same as with other exceptions during inheritance, convert those thrown during delayed class loading into fatal errors. We can't properly deal with such exceptions, as inheritance cannot be gracefully aborted at this point. Fixes oss-fuzz #39405.
1 parent 68ee1b4 commit c8fa477

File tree

4 files changed

+28
-8
lines changed

4 files changed

+28
-8
lines changed

Zend/tests/exception_during_variance_autoload.phpt

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,7 @@ class B extends A {
2222
Y
2323
Q
2424

25-
Warning: Uncaught Error: Class "Q" not found in %s:%d
25+
Fatal error: During inheritance of B, while autoloading Y: Uncaught Error: Class "Q" not found in %s:%d
2626
Stack trace:
2727
#0 %s(%d): {closure}('Y')
28-
#1 {main}
29-
thrown in %s on line %d
30-
31-
Fatal error: Could not check compatibility between B::method(): Y and A::method(): X, because class Y is not available in %s on line %d
28+
#1 {main} in %s on line %d
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
--TEST--
2+
Exception during delayed variance autoload (variation 2)
3+
--FILE--
4+
<?php
5+
spl_autoload_register(function() {
6+
class Y {}
7+
throw new Exception;
8+
});
9+
class A {
10+
function method(): object {}
11+
}
12+
class B extends A {
13+
function method(): Y {}
14+
}
15+
?>
16+
--EXPECTF--
17+
Fatal error: During inheritance of B, while autoloading Y: Uncaught Exception in %s:%d
18+
Stack trace:
19+
#0 %s(%d): {closure}('Y')
20+
#1 {main} in %s on line %d

Zend/zend_compile.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1130,6 +1130,7 @@ ZEND_API zend_class_entry *zend_bind_class_in_slot(
11301130

11311131
ce = zend_do_link_class(ce, lc_parent_name, Z_STR_P(lcname));
11321132
if (ce) {
1133+
ZEND_ASSERT(!EG(exception));
11331134
return ce;
11341135
}
11351136

Zend/zend_inheritance.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2485,7 +2485,7 @@ static int check_variance_obligation(zval *zv) {
24852485
return ZEND_HASH_APPLY_REMOVE;
24862486
}
24872487

2488-
static void load_delayed_classes(void) {
2488+
static void load_delayed_classes(zend_class_entry *ce) {
24892489
HashTable *delayed_autoloads = CG(delayed_autoloads);
24902490
zend_string *name;
24912491

@@ -2499,7 +2499,9 @@ static void load_delayed_classes(void) {
24992499
ZEND_HASH_FOREACH_STR_KEY(delayed_autoloads, name) {
25002500
zend_lookup_class(name);
25012501
if (EG(exception)) {
2502-
break;
2502+
zend_exception_uncaught_error(
2503+
"During inheritance of %s, while autoloading %s",
2504+
ZSTR_VAL(ce->name), ZSTR_VAL(name));
25032505
}
25042506
} ZEND_HASH_FOREACH_END();
25052507

@@ -2908,7 +2910,7 @@ ZEND_API zend_class_entry *zend_do_link_class(zend_class_entry *ce, zend_string
29082910
if (CG(current_linking_class)) {
29092911
ce->ce_flags |= ZEND_ACC_CACHEABLE;
29102912
}
2911-
load_delayed_classes();
2913+
load_delayed_classes(ce);
29122914
if (ce->ce_flags & ZEND_ACC_UNRESOLVED_VARIANCE) {
29132915
resolve_delayed_variance_obligations(ce);
29142916
if (!(ce->ce_flags & ZEND_ACC_LINKED)) {

0 commit comments

Comments
 (0)