]> 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:33:00 +0000 (08:33 +0000)
committerDmitry Stogov <dmitry@php.net>
Wed, 22 Jun 2005 08:33:00 +0000 (08:33 +0000)
NEWS
Zend/tests/bug33257.phpt [new file with mode: 0755]
Zend/zend_compile.c
Zend/zend_compile.h
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

diff --git a/NEWS b/NEWS
index 825615ea7e114102cc8f73a5b9e283b34244397a..54d77cfcf23eb0bc3ba0f55b7487fbbc44b435c6 100644 (file)
--- 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 (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 b407dd4dbd42aca41ee717849628825eba0489e4..aaa488eba4c755c8f6f9cbf80cdacf757898c2fd 100644 (file)
@@ -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) {
index e3b8e5b310a63b8553c77a42aadbe9e7eaee374b..06f54ab218bd08fe19743863000d2e6741aa3383 100644 (file)
@@ -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)                                                                                 \
index 227e06a7c0db70c137e1b2ec05bfb997ff485466..e5673550b07ebd4f796e844e82069aed024d7048 100644 (file)
@@ -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);
index 7c137d7acac551739732c81442b7bf95d5285a31..2aa154982c62d475a653dd5d2d18020c6d9969e8 100644 (file)
@@ -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);