diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2020-05-26 14:59:40 +0200 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2020-05-26 14:59:40 +0200 |
commit | 4a08ca1294ea848fea2a0f87305d3b42226f16dd (patch) | |
tree | fe2467513c580481f2f6f4b9bb3cbe516e2ad8c6 /Zend/zend_vm_execute.h | |
parent | 314ab47e55845862be62683e331aa247025d073d (diff) | |
download | php-git-4a08ca1294ea848fea2a0f87305d3b42226f16dd.tar.gz |
Respect typed references in catch assignment
I decided to null out EG(exception) early here, which means only
the exception from the dtor / ref assign is preserved, and the
previous exception is not chained in. This is more robust, and
I don't think this situation is common enough to be bothered about
the precise behavior.
Diffstat (limited to 'Zend/zend_vm_execute.h')
-rw-r--r-- | Zend/zend_vm_execute.h | 18 |
1 files changed, 8 insertions, 10 deletions
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 559edd070c..13d55291f9 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -3753,17 +3753,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CATCH_SPEC_CONST_HANDLER(ZEND_ exception = EG(exception); ex = EX_VAR(opline->result.var); - if (UNEXPECTED(Z_ISREF_P(ex))) { - ex = Z_REFVAL_P(ex); - } - zval_ptr_dtor(ex); - ZVAL_OBJ(ex, EG(exception)); - if (UNEXPECTED(EG(exception) != exception)) { - GC_ADDREF(EG(exception)); - HANDLE_EXCEPTION(); - } else { + { + /* Always perform a strict assignment. There is a reasonable expectation that if you + * write "catch (Exception $e)" then $e will actually be instanceof Exception. As such, + * we should not permit coercion to string here. */ + zval tmp; + ZVAL_OBJ(&tmp, exception); EG(exception) = NULL; - ZEND_VM_NEXT_OPCODE(); + zend_assign_to_variable(ex, &tmp, IS_TMP_VAR, /* strict */ 1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } } |