diff options
author | Nikita Popov <nikic@php.net> | 2016-07-28 18:45:44 +0200 |
---|---|---|
committer | Nikita Popov <nikic@php.net> | 2016-07-28 18:45:44 +0200 |
commit | 3b48c5a36f7f903ecf206ff5c46a125f7edfee49 (patch) | |
tree | 35583dd508007a7d2c41c4d50c21059372b20e84 /Zend | |
parent | 1693eb9d2a4f8964079934d10712442cd8ed14b2 (diff) | |
download | php-git-3b48c5a36f7f903ecf206ff5c46a125f7edfee49.tar.gz |
Revert "Make call_user_func() on reference args consistent"
This reverts commit fafe01b07bfcb4f4a9088dd89195f2f5acba8fd0.
See bug #72698, there is code using this behavior. Reverting for
PHP 7.0 *only*. The fix is still in PHP 7.1.
Diffstat (limited to 'Zend')
-rw-r--r-- | Zend/tests/call_user_func_006.phpt | 28 | ||||
-rw-r--r-- | Zend/zend_vm_def.h | 43 | ||||
-rw-r--r-- | Zend/zend_vm_execute.h | 84 |
3 files changed, 71 insertions, 84 deletions
diff --git a/Zend/tests/call_user_func_006.phpt b/Zend/tests/call_user_func_006.phpt deleted file mode 100644 index 16a59bcf5b..0000000000 --- a/Zend/tests/call_user_func_006.phpt +++ /dev/null @@ -1,28 +0,0 @@ ---TEST-- -call_user_func() should error on reference arguments ---FILE-- -<?php - -namespace Foo; - -function bar(&$ref) { - $ref = 24; -} - -$x = 42; -$ref =& $x; -\call_user_func('Foo\bar', $x); -var_dump($x); - -$y = 42; -$ref =& $y; -call_user_func('Foo\bar', $y); -var_dump($y); - -?> ---EXPECTF-- -Warning: Parameter 1 to Foo\bar() expected to be a reference, value given in %s on line %d -int(42) - -Warning: Parameter 1 to Foo\bar() expected to be a reference, value given in %s on line %d -int(42) diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index e4fd8e8e28..504bf5783b 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -4660,27 +4660,32 @@ ZEND_VM_HANDLER(120, ZEND_SEND_USER, VAR|CV, ANY) arg = GET_OP1_ZVAL_PTR(BP_VAR_R); param = ZEND_CALL_VAR(EX(call), opline->result.var); - if (UNEXPECTED(ARG_MUST_BE_SENT_BY_REF(EX(call)->func, opline->op2.num))) { - zend_error(E_WARNING, "Parameter %d to %s%s%s() expected to be a reference, value given", - opline->op2.num, - EX(call)->func->common.scope ? ZSTR_VAL(EX(call)->func->common.scope->name) : "", - EX(call)->func->common.scope ? "::" : "", - ZSTR_VAL(EX(call)->func->common.function_name)); + if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) { + if (UNEXPECTED(!Z_ISREF_P(arg))) { + if (!ARG_MAY_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) { - if (ZEND_CALL_INFO(EX(call)) & ZEND_CALL_CLOSURE) { - OBJ_RELEASE((zend_object*)EX(call)->func->common.prototype); - } - if (Z_OBJ(EX(call)->This)) { - OBJ_RELEASE(Z_OBJ(EX(call)->This)); - } - ZVAL_UNDEF(param); - EX(call)->func = (zend_function*)&zend_pass_function; - EX(call)->called_scope = NULL; - Z_OBJ(EX(call)->This) = NULL; - ZEND_SET_CALL_INFO(EX(call), ZEND_CALL_INFO(EX(call)) & ~ZEND_CALL_RELEASE_THIS); + zend_error(E_WARNING, "Parameter %d to %s%s%s() expected to be a reference, value given", + opline->op2.num, + EX(call)->func->common.scope ? ZSTR_VAL(EX(call)->func->common.scope->name) : "", + EX(call)->func->common.scope ? "::" : "", + ZSTR_VAL(EX(call)->func->common.function_name)); - FREE_OP1(); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + if (ZEND_CALL_INFO(EX(call)) & ZEND_CALL_CLOSURE) { + OBJ_RELEASE((zend_object*)EX(call)->func->common.prototype); + } + if (Z_OBJ(EX(call)->This)) { + OBJ_RELEASE(Z_OBJ(EX(call)->This)); + } + ZVAL_UNDEF(param); + EX(call)->func = (zend_function*)&zend_pass_function; + EX(call)->called_scope = NULL; + Z_OBJ(EX(call)->This) = NULL; + ZEND_SET_CALL_INFO(EX(call), ZEND_CALL_INFO(EX(call)) & ~ZEND_CALL_RELEASE_THIS); + + FREE_OP1(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + } } else { if (Z_ISREF_P(arg) && !(EX(call)->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) { diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 0103128183..b6375908b0 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -15371,27 +15371,32 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_USER_SPEC_VAR_HANDLER(ZEN arg = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); param = ZEND_CALL_VAR(EX(call), opline->result.var); - if (UNEXPECTED(ARG_MUST_BE_SENT_BY_REF(EX(call)->func, opline->op2.num))) { - zend_error(E_WARNING, "Parameter %d to %s%s%s() expected to be a reference, value given", - opline->op2.num, - EX(call)->func->common.scope ? ZSTR_VAL(EX(call)->func->common.scope->name) : "", - EX(call)->func->common.scope ? "::" : "", - ZSTR_VAL(EX(call)->func->common.function_name)); + if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) { + if (UNEXPECTED(!Z_ISREF_P(arg))) { + if (!ARG_MAY_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) { - if (ZEND_CALL_INFO(EX(call)) & ZEND_CALL_CLOSURE) { - OBJ_RELEASE((zend_object*)EX(call)->func->common.prototype); - } - if (Z_OBJ(EX(call)->This)) { - OBJ_RELEASE(Z_OBJ(EX(call)->This)); - } - ZVAL_UNDEF(param); - EX(call)->func = (zend_function*)&zend_pass_function; - EX(call)->called_scope = NULL; - Z_OBJ(EX(call)->This) = NULL; - ZEND_SET_CALL_INFO(EX(call), ZEND_CALL_INFO(EX(call)) & ~ZEND_CALL_RELEASE_THIS); + zend_error(E_WARNING, "Parameter %d to %s%s%s() expected to be a reference, value given", + opline->op2.num, + EX(call)->func->common.scope ? ZSTR_VAL(EX(call)->func->common.scope->name) : "", + EX(call)->func->common.scope ? "::" : "", + ZSTR_VAL(EX(call)->func->common.function_name)); - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + if (ZEND_CALL_INFO(EX(call)) & ZEND_CALL_CLOSURE) { + OBJ_RELEASE((zend_object*)EX(call)->func->common.prototype); + } + if (Z_OBJ(EX(call)->This)) { + OBJ_RELEASE(Z_OBJ(EX(call)->This)); + } + ZVAL_UNDEF(param); + EX(call)->func = (zend_function*)&zend_pass_function; + EX(call)->called_scope = NULL; + Z_OBJ(EX(call)->This) = NULL; + ZEND_SET_CALL_INFO(EX(call), ZEND_CALL_INFO(EX(call)) & ~ZEND_CALL_RELEASE_THIS); + + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + } } else { if (Z_ISREF_P(arg) && !(EX(call)->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) { @@ -28992,26 +28997,31 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_USER_SPEC_CV_HANDLER(ZEND arg = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var); param = ZEND_CALL_VAR(EX(call), opline->result.var); - if (UNEXPECTED(ARG_MUST_BE_SENT_BY_REF(EX(call)->func, opline->op2.num))) { - zend_error(E_WARNING, "Parameter %d to %s%s%s() expected to be a reference, value given", - opline->op2.num, - EX(call)->func->common.scope ? ZSTR_VAL(EX(call)->func->common.scope->name) : "", - EX(call)->func->common.scope ? "::" : "", - ZSTR_VAL(EX(call)->func->common.function_name)); + if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) { + if (UNEXPECTED(!Z_ISREF_P(arg))) { + if (!ARG_MAY_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) { - if (ZEND_CALL_INFO(EX(call)) & ZEND_CALL_CLOSURE) { - OBJ_RELEASE((zend_object*)EX(call)->func->common.prototype); - } - if (Z_OBJ(EX(call)->This)) { - OBJ_RELEASE(Z_OBJ(EX(call)->This)); - } - ZVAL_UNDEF(param); - EX(call)->func = (zend_function*)&zend_pass_function; - EX(call)->called_scope = NULL; - Z_OBJ(EX(call)->This) = NULL; - ZEND_SET_CALL_INFO(EX(call), ZEND_CALL_INFO(EX(call)) & ~ZEND_CALL_RELEASE_THIS); + zend_error(E_WARNING, "Parameter %d to %s%s%s() expected to be a reference, value given", + opline->op2.num, + EX(call)->func->common.scope ? ZSTR_VAL(EX(call)->func->common.scope->name) : "", + EX(call)->func->common.scope ? "::" : "", + ZSTR_VAL(EX(call)->func->common.function_name)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + if (ZEND_CALL_INFO(EX(call)) & ZEND_CALL_CLOSURE) { + OBJ_RELEASE((zend_object*)EX(call)->func->common.prototype); + } + if (Z_OBJ(EX(call)->This)) { + OBJ_RELEASE(Z_OBJ(EX(call)->This)); + } + ZVAL_UNDEF(param); + EX(call)->func = (zend_function*)&zend_pass_function; + EX(call)->called_scope = NULL; + Z_OBJ(EX(call)->This) = NULL; + ZEND_SET_CALL_INFO(EX(call), ZEND_CALL_INFO(EX(call)) & ~ZEND_CALL_RELEASE_THIS); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + } } else { if (Z_ISREF_P(arg) && !(EX(call)->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) { |