Skip to content

Commit be82173

Browse files
committed
Bail on exception during delayed autoload
We shouldn't try to load further classes if one autoload throws. This fixes oss-fuzz #38881, though I believe there are still two deeper issues here: 1) Why do we allow autoloading with an active exception? 2) Exception save & restore should probably also save and restore the exception opline.
1 parent 4304542 commit be82173

File tree

2 files changed

+34
-0
lines changed

2 files changed

+34
-0
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
--TEST--
2+
Exception during delayed variance autoload
3+
--FILE--
4+
<?php
5+
spl_autoload_register(function($class) {
6+
echo "$class\n";
7+
if ($class == 'X') {
8+
new Y;
9+
}
10+
if ($class == 'Y') {
11+
new Q;
12+
}
13+
});
14+
class A {
15+
function method(): X {}
16+
}
17+
class B extends A {
18+
function method(): Y {}
19+
}
20+
?>
21+
--EXPECTF--
22+
Y
23+
Q
24+
25+
Warning: Uncaught Error: Class "Q" not found in %s:%d
26+
Stack trace:
27+
#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

Zend/zend_inheritance.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2348,6 +2348,9 @@ static void load_delayed_classes() {
23482348

23492349
ZEND_HASH_FOREACH_STR_KEY(delayed_autoloads, name) {
23502350
zend_lookup_class(name);
2351+
if (EG(exception)) {
2352+
break;
2353+
}
23512354
} ZEND_HASH_FOREACH_END();
23522355

23532356
zend_hash_destroy(delayed_autoloads);

0 commit comments

Comments
 (0)