summaryrefslogtreecommitdiff
path: root/Zend/zend_execute_API.c
diff options
context:
space:
mode:
authorChristoph M. Becker <cmbecker69@gmx.de>2020-08-24 15:02:15 +0200
committerChristoph M. Becker <cmbecker69@gmx.de>2020-08-24 15:03:26 +0200
commit5643f34a1ed71ae33d313e31ebb8c814cc8e3c0a (patch)
tree433cd52ec49de2fa2d70bc2abc7ecfb7c9f5f11f /Zend/zend_execute_API.c
parentbfeb2f6abc35309f25074410ee7eb61f59c22274 (diff)
parent6b6c2c003c69729832a7804c76bff6e230b73c91 (diff)
downloadphp-git-5643f34a1ed71ae33d313e31ebb8c814cc8e3c0a.tar.gz
Merge branch 'PHP-7.4' into master
* PHP-7.4: Fix #79979: passing value to by-ref param via CUFA crashes
Diffstat (limited to 'Zend/zend_execute_API.c')
-rw-r--r--Zend/zend_execute_API.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c
index b3d6319560..ece3679822 100644
--- a/Zend/zend_execute_API.c
+++ b/Zend/zend_execute_API.c
@@ -734,6 +734,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache) /
for (i=0; i<fci->param_count; i++) {
zval *param = ZEND_CALL_ARG(call, i+1);
zval *arg = &fci->params[i];
+ zend_bool must_wrap = 0;
if (UNEXPECTED(Z_ISUNDEF_P(arg))) {
/* Allow forwarding undef slots. This is only used by Closure::__invoke(). */
ZVAL_UNDEF(param);
@@ -745,8 +746,9 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache) /
if (UNEXPECTED(!Z_ISREF_P(arg))) {
if (!ARG_MAY_BE_SENT_BY_REF(func, i + 1)) {
/* By-value send is not allowed -- emit a warning,
- * but still perform the call with a by-value send. */
+ * and perform the call with the value wrapped in a reference. */
zend_param_must_be_ref(func, i + 1);
+ must_wrap = 1;
if (UNEXPECTED(EG(exception))) {
ZEND_CALL_NUM_ARGS(call) = i;
cleanup_args:
@@ -767,7 +769,11 @@ cleanup_args:
}
}
- ZVAL_COPY(param, arg);
+ if (EXPECTED(!must_wrap)) {
+ ZVAL_COPY(param, arg);
+ } else {
+ ZVAL_NEW_REF(param, arg);
+ }
}
if (fci->named_params) {
@@ -775,6 +781,7 @@ cleanup_args:
zval *arg;
uint32_t arg_num = ZEND_CALL_NUM_ARGS(call) + 1;
zend_bool have_named_params = 0;
+ zend_bool must_wrap = 0;
ZEND_HASH_FOREACH_STR_KEY_VAL(fci->named_params, name, arg) {
zval *target;
if (name) {
@@ -799,8 +806,9 @@ cleanup_args:
if (UNEXPECTED(!Z_ISREF_P(arg))) {
if (!ARG_MAY_BE_SENT_BY_REF(func, arg_num)) {
/* By-value send is not allowed -- emit a warning,
- * but still perform the call with a by-value send. */
+ * and perform the call with the value wrapped in a reference. */
zend_param_must_be_ref(func, arg_num);
+ must_wrap = 1;
if (UNEXPECTED(EG(exception))) {
goto cleanup_args;
}
@@ -814,7 +822,11 @@ cleanup_args:
}
}
- ZVAL_COPY(target, arg);
+ if (EXPECTED(!must_wrap)) {
+ ZVAL_COPY(target, arg);
+ } else {
+ ZVAL_NEW_REF(target, arg);
+ }
if (!name) {
ZEND_CALL_NUM_ARGS(call)++;
arg_num++;