Skip to content

Commit

Permalink
Fix finally exception chaining on recursion
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
nikic committed Nov 1, 2021
1 parent 91dfac6 commit 1a2fb90
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 4 deletions.
18 changes: 18 additions & 0 deletions Zend/tests/try/try_finally_recursive_previous.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
--TEST--
Test case where the implicit previous finally exception would result in recursion
--FILE--
<?php
try {
$e = new Exception("M1");
try {
throw new Exception("M2", 0, $e);
} finally {
throw $e;
}
} finally {}
?>
--EXPECTF--
Fatal error: Uncaught Exception: M1 in %s:%d
Stack trace:
#0 {main}
thrown in %s on line %d
3 changes: 1 addition & 2 deletions Zend/zend_vm_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -7714,9 +7714,8 @@ ZEND_VM_HELPER(zend_dispatch_try_catch_finally_helper, ANY, ANY, uint32_t try_ca
if (ex) {
zend_exception_set_previous(ex, Z_OBJ_P(fast_call));
} else {
EG(exception) = Z_OBJ_P(fast_call);
ex = EG(exception) = Z_OBJ_P(fast_call);
}
ex = Z_OBJ_P(fast_call);
}
}
}
Expand Down
3 changes: 1 addition & 2 deletions Zend/zend_vm_execute.h
Original file line number Diff line number Diff line change
Expand Up @@ -2905,9 +2905,8 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_dispatch_try
if (ex) {
zend_exception_set_previous(ex, Z_OBJ_P(fast_call));
} else {
EG(exception) = Z_OBJ_P(fast_call);
ex = EG(exception) = Z_OBJ_P(fast_call);
}
ex = Z_OBJ_P(fast_call);
}
}
}
Expand Down

0 comments on commit 1a2fb90

Please sign in to comment.