From: Stanislav Malyshev Date: Tue, 18 Aug 2009 20:51:49 +0000 (+0000) Subject: fix crash when unexpectedly passed by-ref parameter is modified X-Git-Tag: php-5.4.0alpha1~191^2~2782 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=deb7825601e069549b12f22309a1466afeb3d22d;p=php fix crash when unexpectedly passed by-ref parameter is modified --- diff --git a/Zend/tests/unexpected_ref_bug.phpt b/Zend/tests/unexpected_ref_bug.phpt new file mode 100755 index 0000000000..61fe1aa5b1 --- /dev/null +++ b/Zend/tests/unexpected_ref_bug.phpt @@ -0,0 +1,18 @@ +--TEST-- +Crash when function parameter modified via unexpected reference +--FILE-- + +--EXPECTF-- +Done. diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 399dcfbfee..4e7fd16133 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -872,6 +872,12 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS for (i=0; iparam_count; i++) { zval *param; + if(EX(function_state).function->type == ZEND_INTERNAL_FUNCTION + && !ARG_SHOULD_BE_SENT_BY_REF(EX(function_state).function, i + 1) + && PZVAL_IS_REF(*fci->params[i])) { + SEPARATE_ZVAL(fci->params[i]); + } + if (ARG_SHOULD_BE_SENT_BY_REF(EX(function_state).function, i + 1) && !PZVAL_IS_REF(*fci->params[i])) { if (Z_REFCOUNT_PP(fci->params[i]) > 1) { diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 76d499b42a..da5ae97935 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -2776,6 +2776,10 @@ ZEND_VM_HANDLER(67, ZEND_SEND_REF, VAR|CV, ANY) zend_error_noreturn(E_ERROR, "Only variables can be passed by reference"); } + if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION && !ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) { + ZEND_VM_DISPATCH_TO_HELPER(zend_send_by_var_helper); + } + SEPARATE_ZVAL_TO_MAKE_IS_REF(varptr_ptr); varptr = *varptr_ptr; Z_ADDREF_P(varptr); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 405b7debdf..ee032d1ec6 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -8618,6 +8618,10 @@ static int ZEND_FASTCALL ZEND_SEND_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG zend_error_noreturn(E_ERROR, "Only variables can be passed by reference"); } + if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION && !ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) { + return zend_send_by_var_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + } + SEPARATE_ZVAL_TO_MAKE_IS_REF(varptr_ptr); varptr = *varptr_ptr; Z_ADDREF_P(varptr); @@ -23163,6 +23167,10 @@ static int ZEND_FASTCALL ZEND_SEND_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS zend_error_noreturn(E_ERROR, "Only variables can be passed by reference"); } + if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION && !ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) { + return zend_send_by_var_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + } + SEPARATE_ZVAL_TO_MAKE_IS_REF(varptr_ptr); varptr = *varptr_ptr; Z_ADDREF_P(varptr);