summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@php.net>2005-06-22 08:31:19 +0000
committerDmitry Stogov <dmitry@php.net>2005-06-22 08:31:19 +0000
commit21bdd33fffed2bc4762359ff7b7da50154f0e104 (patch)
treec64cb8e5a4f9f6b6c9031d7bb9999cd3348834d6
parentb857a3579f3faa29b8942466285ac9dcf52ffcd0 (diff)
downloadphp-git-21bdd33fffed2bc4762359ff7b7da50154f0e104.tar.gz
Fixed bug #33257 (array_splice() inconsistent when passed function instead of variable)
-rw-r--r--NEWS2
-rwxr-xr-xZend/tests/bug33257.phpt17
-rw-r--r--Zend/zend_compile.c6
-rw-r--r--Zend/zend_compile.h1
-rw-r--r--Zend/zend_execute.c5
5 files changed, 28 insertions, 3 deletions
diff --git a/NEWS b/NEWS
index cc85e6295b..9b8d9f527e 100644
--- a/NEWS
+++ b/NEWS
@@ -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);