--- /dev/null
+--TEST--
+Crash when function parameter modified via unexpected reference
+--FILE--
+<?php
+function my_errorhandler($errno,$errormsg) {
+ global $my_var;
+ $my_var = 0;
+ return true;
+}
+set_error_handler("my_errorhandler");
+$my_var = str_repeat("A",64);
+$data = call_user_func_array("explode",array(new StdClass(), &$my_var));
+$my_var=array(1,2,3);
+$data = call_user_func_array("implode",array(&$my_var, new StdClass()));
+echo "Done.\n";
+?>
+--EXPECTF--
+Done.
for (i=0; i<fci->param_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])) {
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);
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);
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);
--- /dev/null
+--TEST--
+Crash when function parameter modified via reference
+--FILE--
+<?php
+function usercompare($a,$b) {
+ unset($GLOBALS['my_var'][2]);
+ return 0;
+}
+$my_var = array(1 => "entry_1",
+2 => "entry_2",
+3 => "entry_3",
+4 => "entry_4",
+5 => "entry_5");
+usort($my_var, "usercompare");
+
+echo "Done.\n";
+?>
+--EXPECTF--
+
+Warning: usort(): Array was modified by the user comparison function in %s on line %d
+Done.