]> granicus.if.org Git - php/commitdiff
Fixed bug #33257 (array_splice() inconsistent when passed function instead of variable)
authorDmitry Stogov <dmitry@php.net>
Wed, 22 Jun 2005 08:31:19 +0000 (08:31 +0000)
committerDmitry Stogov <dmitry@php.net>
Wed, 22 Jun 2005 08:31:19 +0000 (08:31 +0000)
NEWS
Zend/tests/bug33257.phpt [new file with mode: 0755]
Zend/zend_compile.c
Zend/zend_compile.h
Zend/zend_execute.c

diff --git a/NEWS b/NEWS
index cc85e6295b5fa5b7b23264423ac6418e4fe5e71b..9b8d9f527e358dba916456fad03f6e3c2901d6e6 100644 (file)
--- 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 (executable)
index 0000000..b3e9800
--- /dev/null
@@ -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
index 67a6d27e1cbf40b95a176ef02e8edff8a2d6f306..4656b448a531a3240f9638ff56518d08fc16fb65 100644 (file)
@@ -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) {
index 7b00196e013836d7c23c2722bb640bed9be7baac..c17b49eb5fa5a27457a5a49c1e1a3725e27c1252 100644 (file)
@@ -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) { \
index 514f47d167f22f888d2883c133ac6085b555340a..711f89dd571da6183bb61d004d1e5cf4e6bb6bb0 100644 (file)
@@ -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);