summaryrefslogtreecommitdiff
path: root/Zend/zend_vm_def.h
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2020-05-26 14:59:40 +0200
committerNikita Popov <nikita.ppv@gmail.com>2020-05-26 14:59:40 +0200
commit4a08ca1294ea848fea2a0f87305d3b42226f16dd (patch)
treefe2467513c580481f2f6f4b9bb3cbe516e2ad8c6 /Zend/zend_vm_def.h
parent314ab47e55845862be62683e331aa247025d073d (diff)
downloadphp-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_def.h')
-rw-r--r--Zend/zend_vm_def.h18
1 files changed, 8 insertions, 10 deletions
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index 8a9d74c1f8..1039b902e7 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -4632,17 +4632,15 @@ ZEND_VM_HANDLER(107, ZEND_CATCH, CONST, JMP_ADDR, LAST_CATCH|CACHE_SLOT)
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();
}
}