From 21e071be0692157ab8c6a86c44911e0bc80d75a8 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 22 Jun 2005 08:33:00 +0000 Subject: [PATCH] Fixed bug #33257 (array_splice() inconsistent when passed function instead of variable) --- NEWS | 2 ++ Zend/tests/bug33257.phpt | 17 +++++++++++++++++ Zend/zend_compile.c | 6 ++++-- Zend/zend_compile.h | 1 + Zend/zend_vm_def.h | 5 ++++- Zend/zend_vm_execute.h | 10 ++++++++-- 6 files changed, 36 insertions(+), 5 deletions(-) create mode 100755 Zend/tests/bug33257.phpt diff --git a/NEWS b/NEWS index 825615ea7e..54d77cfcf2 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,8 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? 2005, PHP 5.1 Beta 3? - Fixed bug #33427 (ext/odbc: check if unixODBC header file exists). (Jani) +- Fixed bug #33257 (array_splice() inconsistent when passed function instead + of variable). (Dmitry) 21 Jun 2005, PHP 5.1 Beta 2 - Improved PHP extension loading mechanism with support for module dependencies diff --git a/Zend/tests/bug33257.phpt b/Zend/tests/bug33257.phpt new file mode 100755 index 0000000000..b3e98003a3 --- /dev/null +++ b/Zend/tests/bug33257.phpt @@ -0,0 +1,17 @@ +--TEST-- +Bug #33257 array_splice() inconsistent when passed function instead of variable +--FILE-- + +--EXPECTF-- +Fatal error: Only variables can be passed by reference in %sbug33257.php on line 10 diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index b407dd4dbd..aaa488eba4 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -1476,6 +1476,7 @@ void zend_do_pass_param(znode *param, zend_uchar op, int offset TSRMLS_DC) int original_op=op; zend_function **function_ptr_ptr, *function_ptr; int send_by_reference; + int send_function = 0; zend_stack_top(&CG(function_call_stack), (void **) &function_ptr_ptr); function_ptr = *function_ptr_ptr; @@ -1500,6 +1501,7 @@ void zend_do_pass_param(znode *param, zend_uchar op, int offset TSRMLS_DC) if (op == ZEND_SEND_VAR && zend_is_function_or_method_call(param)) { /* Method call */ op = ZEND_SEND_VAR_NO_REF; + send_function = ZEND_ARG_SEND_FUNCTION; } else if (op == ZEND_SEND_VAL && (param->op_type & (IS_VAR|IS_CV))) { op = ZEND_SEND_VAR_NO_REF; } @@ -1539,9 +1541,9 @@ void zend_do_pass_param(znode *param, zend_uchar op, int offset TSRMLS_DC) if (op == ZEND_SEND_VAR_NO_REF) { if (function_ptr) { - opline->extended_value = ZEND_ARG_COMPILE_TIME_BOUND | send_by_reference; + opline->extended_value = ZEND_ARG_COMPILE_TIME_BOUND | send_by_reference | send_function; } else { - opline->extended_value = 0; + opline->extended_value = send_function; } } else { if (function_ptr) { diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index e3b8e5b310..06f54ab218 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -644,6 +644,7 @@ int zendlex(znode *zendlval TSRMLS_DC); #define ZEND_ARG_SEND_BY_REF (1<<0) #define ZEND_ARG_COMPILE_TIME_BOUND (1<<1) +#define ZEND_ARG_SEND_FUNCTION (1<<2) /* Lost In Stupid Parentheses */ #define ARG_SHOULD_BE_SENT_BY_REF(zf, arg_num) \ diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 227e06a7c0..e5673550b0 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -2158,7 +2158,10 @@ ZEND_VM_HANDLER(106, ZEND_SEND_VAR_NO_REF, VAR|CV, ANY) } else if (!ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) { ZEND_VM_DISPATCH_TO_HELPER(zend_send_by_var_helper); } - { + if ((opline->extended_value & ZEND_ARG_SEND_FUNCTION) && + !EX_T(opline->op1.u.var).var.fcall_returned_reference) { + zend_error(E_ERROR, "Only variables can be passed by reference"); + } else { zval *varptr; zend_free_op free_op1; varptr = GET_OP1_ZVAL_PTR(BP_VAR_R); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 7c137d7aca..2aa154982c 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -7064,7 +7064,10 @@ static int ZEND_SEND_VAR_NO_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } else if (!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); } - { + if ((opline->extended_value & ZEND_ARG_SEND_FUNCTION) && + !EX_T(opline->op1.u.var).var.fcall_returned_reference) { + zend_error(E_ERROR, "Only variables can be passed by reference"); + } else { zval *varptr; zend_free_op free_op1; varptr = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); @@ -19080,7 +19083,10 @@ static int ZEND_SEND_VAR_NO_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } else if (!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); } - { + if ((opline->extended_value & ZEND_ARG_SEND_FUNCTION) && + !EX_T(opline->op1.u.var).var.fcall_returned_reference) { + zend_error(E_ERROR, "Only variables can be passed by reference"); + } else { zval *varptr; varptr = _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC); -- 2.50.1