diff options
author | Christoph M. Becker <cmbecker69@gmx.de> | 2020-08-24 15:02:15 +0200 |
---|---|---|
committer | Christoph M. Becker <cmbecker69@gmx.de> | 2020-08-24 15:03:26 +0200 |
commit | 5643f34a1ed71ae33d313e31ebb8c814cc8e3c0a (patch) | |
tree | 433cd52ec49de2fa2d70bc2abc7ecfb7c9f5f11f /Zend/zend_execute_API.c | |
parent | bfeb2f6abc35309f25074410ee7eb61f59c22274 (diff) | |
parent | 6b6c2c003c69729832a7804c76bff6e230b73c91 (diff) | |
download | php-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.c | 20 |
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++; |