diff options
author | Dmitry Stogov <dmitry@php.net> | 2005-06-22 08:31:19 +0000 |
---|---|---|
committer | Dmitry Stogov <dmitry@php.net> | 2005-06-22 08:31:19 +0000 |
commit | 21bdd33fffed2bc4762359ff7b7da50154f0e104 (patch) | |
tree | c64cb8e5a4f9f6b6c9031d7bb9999cd3348834d6 | |
parent | b857a3579f3faa29b8942466285ac9dcf52ffcd0 (diff) | |
download | php-git-21bdd33fffed2bc4762359ff7b7da50154f0e104.tar.gz |
Fixed bug #33257 (array_splice() inconsistent when passed function instead of variable)
-rw-r--r-- | NEWS | 2 | ||||
-rwxr-xr-x | Zend/tests/bug33257.phpt | 17 | ||||
-rw-r--r-- | Zend/zend_compile.c | 6 | ||||
-rw-r--r-- | Zend/zend_compile.h | 1 | ||||
-rw-r--r-- | Zend/zend_execute.c | 5 |
5 files changed, 28 insertions, 3 deletions
@@ -19,6 +19,8 @@ PHP NEWS - Fixed bug #33268 (iconv_strlen() works only with a parameter of < 3 in length). (Ilia) - Fixed bug #33263 (mysqli_real_escape doesn't work in __construct) (Georg) +- Fixed bug #33257 (array_splice() inconsistent when passed function instead + of variable). (Dmitry) - Fixed bug #33243 (ze1_compatibility_mode does not work as expected). (Dmitry) - Fixed bug #33242 (Mangled error message when stream fails). (Derick) - Fixed bug #33222 (segfault when CURL handle is closed in a callback). (Tony) 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-- +<?php +class X { + protected static $arr = array("a", "b", "c"); + public static function getArr() { + return self::$arr; + } +} + +//$arr1 = X::getArr(); +array_splice(X::getArr(), 1, 1); +print_r(X::getArr()); +?> +--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 67a6d27e1c..4656b448a5 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -1379,6 +1379,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; @@ -1403,6 +1404,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) { op = ZEND_SEND_VAR_NO_REF; } @@ -1441,9 +1443,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 7b00196e01..c17b49eb5f 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -804,6 +804,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) #define AI_USE_PTR(ai) \ if ((ai).ptr_ptr) { \ diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 514f47d167..711f89dd57 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -3037,7 +3037,10 @@ int zend_send_var_no_ref_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(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(&opline->op1, EX(Ts), &EG(free_op1), BP_VAR_R); |