Skip to content

Commit 1a2fb90

Browse files
committed
Fix finally exception chaining on recursion
In this case zend_exception_set_previous() would destroy the fast_call exception and further accesses on ex would be invalid. We should only update ex if we update EG(exception). Fixes oss-fuzz #40464.
1 parent 91dfac6 commit 1a2fb90

File tree

3 files changed

+20
-4
lines changed

3 files changed

+20
-4
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
--TEST--
2+
Test case where the implicit previous finally exception would result in recursion
3+
--FILE--
4+
<?php
5+
try {
6+
$e = new Exception("M1");
7+
try {
8+
throw new Exception("M2", 0, $e);
9+
} finally {
10+
throw $e;
11+
}
12+
} finally {}
13+
?>
14+
--EXPECTF--
15+
Fatal error: Uncaught Exception: M1 in %s:%d
16+
Stack trace:
17+
#0 {main}
18+
thrown in %s on line %d

Zend/zend_vm_def.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7714,9 +7714,8 @@ ZEND_VM_HELPER(zend_dispatch_try_catch_finally_helper, ANY, ANY, uint32_t try_ca
77147714
if (ex) {
77157715
zend_exception_set_previous(ex, Z_OBJ_P(fast_call));
77167716
} else {
7717-
EG(exception) = Z_OBJ_P(fast_call);
7717+
ex = EG(exception) = Z_OBJ_P(fast_call);
77187718
}
7719-
ex = Z_OBJ_P(fast_call);
77207719
}
77217720
}
77227721
}

Zend/zend_vm_execute.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2905,9 +2905,8 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_dispatch_try
29052905
if (ex) {
29062906
zend_exception_set_previous(ex, Z_OBJ_P(fast_call));
29072907
} else {
2908-
EG(exception) = Z_OBJ_P(fast_call);
2908+
ex = EG(exception) = Z_OBJ_P(fast_call);
29092909
}
2910-
ex = Z_OBJ_P(fast_call);
29112910
}
29122911
}
29132912
}

0 commit comments

Comments
 (0)