]> granicus.if.org Git - php/commitdiff
Fixed bug #34064 (arr[] as param to function in class gives invalid opcode)
authorDmitry Stogov <dmitry@php.net>
Wed, 10 Aug 2005 10:39:28 +0000 (10:39 +0000)
committerDmitry Stogov <dmitry@php.net>
Wed, 10 Aug 2005 10:39:28 +0000 (10:39 +0000)
NEWS
Zend/tests/bug34064.phpt [new file with mode: 0755]
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

diff --git a/NEWS b/NEWS
index 203a0bbd1967735cebdb72f06647df0b70051dfa..8b063ee90d089c197e1cb4ffd05560fe4e270f85 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -20,6 +20,8 @@ PHP                                                                        NEWS
 - Fixed "make test" to work for phpized extensions. (Hartmut, Jani)
 - Fixed failing queries (FALSE returned) with mysqli_query() on 64 bit systems.
   (Andrey)
+- Fixed bug #34064 (arr[] as param to function in class gives invalid opcode).
+  (Dmitry)
 - Fixed bug #34045 (Buffer overflow with serialized object). (Dmitry)
 - Fixed bug #33999 (object remains object when cast to int). (Dmitry)
 - Fixed bug #33996 (No information given for fatal error on passing invalid
diff --git a/Zend/tests/bug34064.phpt b/Zend/tests/bug34064.phpt
new file mode 100755 (executable)
index 0000000..84208a5
--- /dev/null
@@ -0,0 +1,35 @@
+--TEST--
+Bug #34064 (arr[] as param to function in class gives invalid opcode)
+--FILE--
+<?php
+class XmlTest {
+
+    function test_ref(&$test)
+    {
+       $test = "ok";
+    }
+
+    function test($test)
+    {
+    }
+
+    function run()
+    {
+        $ar = array();
+        $this->test_ref($ar[]);
+        var_dump($ar);
+        $this->test($ar[]);
+    }
+}
+
+$o = new XmlTest();
+$o->run();
+?>
+--EXPECTF--
+array(1) {
+  [0]=>
+  string(2) "ok"
+}
+
+Fatal error: Cannot use [] for reading in %sbug34064.php on line 18
+
index 92942b1593b13a99b15fc67d3a3860f2a372b5e2..805c31cb0bc790db2214643c4c0ca10b7bfc2e09 100644 (file)
@@ -1051,7 +1051,7 @@ ZEND_VM_HANDLER(84, ZEND_FETCH_DIM_W, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
        ZEND_VM_NEXT_OPCODE();
 }
 
-ZEND_VM_HANDLER(87, ZEND_FETCH_DIM_RW, VAR|CV, CONST|TMP|VAR|CV)
+ZEND_VM_HANDLER(87, ZEND_FETCH_DIM_RW, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
 {
        zend_op *opline = EX(opline);
        zend_free_op free_op1, free_op2;
@@ -1075,13 +1075,17 @@ ZEND_VM_HANDLER(90, ZEND_FETCH_DIM_IS, VAR|CV, CONST|TMP|VAR|CV)
        ZEND_VM_NEXT_OPCODE();
 }
 
-ZEND_VM_HANDLER(93, ZEND_FETCH_DIM_FUNC_ARG, VAR|CV, CONST|TMP|VAR|CV)
+ZEND_VM_HANDLER(93, ZEND_FETCH_DIM_FUNC_ARG, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
 {
        zend_op *opline = EX(opline);
        zend_free_op free_op1, free_op2;
        int type = ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)?BP_VAR_W:BP_VAR_R;
-       zval *dim = GET_OP2_ZVAL_PTR(BP_VAR_R);
-
+       zval *dim;
+       
+       if (OP2_TYPE == IS_UNUSED && type == BP_VAR_R) {
+               zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
+       }
+       dim = GET_OP2_ZVAL_PTR(BP_VAR_R);
        zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), GET_OP1_ZVAL_PTR_PTR(type), dim, IS_OP2_TMP_FREE(), type TSRMLS_CC);
        FREE_OP2();
        FREE_OP1_VAR_PTR();
index d1f492836f3bb17c48e040e9ca842124a46e19b8..81a60695f8b44ca1db53775af02639e32a3a6a9e 100644 (file)
@@ -8529,8 +8529,12 @@ static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR
        zend_op *opline = EX(opline);
        zend_free_op free_op1;
        int type = ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)?BP_VAR_W:BP_VAR_R;
-       zval *dim = &opline->op2.u.constant;
-
+       zval *dim;
+       
+       if (IS_CONST == IS_UNUSED && type == BP_VAR_R) {
+               zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
+       }
+       dim = &opline->op2.u.constant;
        zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, type TSRMLS_CC);
 
        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -9945,8 +9949,12 @@ static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS
        zend_op *opline = EX(opline);
        zend_free_op free_op1, free_op2;
        int type = ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)?BP_VAR_W:BP_VAR_R;
-       zval *dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
-
+       zval *dim;
+       
+       if (IS_TMP_VAR == IS_UNUSED && type == BP_VAR_R) {
+               zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
+       }
+       dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
        zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 1, type TSRMLS_CC);
        zval_dtor(free_op2.var);
        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -11364,8 +11372,12 @@ static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS
        zend_op *opline = EX(opline);
        zend_free_op free_op1, free_op2;
        int type = ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)?BP_VAR_W:BP_VAR_R;
-       zval *dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
-
+       zval *dim;
+       
+       if (IS_VAR == IS_UNUSED && type == BP_VAR_R) {
+               zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
+       }
+       dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
        zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, type TSRMLS_CC);
        if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -12359,6 +12371,35 @@ static int ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        ZEND_VM_NEXT_OPCODE();
 }
 
+static int ZEND_FETCH_DIM_RW_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+       zend_op *opline = EX(opline);
+       zend_free_op free_op1;
+       zval *dim = NULL;
+
+       zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_RW TSRMLS_CC);
+
+       if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+       ZEND_VM_NEXT_OPCODE();
+}
+
+static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+       zend_op *opline = EX(opline);
+       zend_free_op free_op1;
+       int type = ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)?BP_VAR_W:BP_VAR_R;
+       zval *dim;
+       
+       if (IS_UNUSED == IS_UNUSED && type == BP_VAR_R) {
+               zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
+       }
+       dim = NULL;
+       zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, type TSRMLS_CC);
+
+       if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+       ZEND_VM_NEXT_OPCODE();
+}
+
 static int ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        zend_op *opline = EX(opline);
@@ -13199,8 +13240,12 @@ static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zend_op *opline = EX(opline);
        zend_free_op free_op1;
        int type = ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)?BP_VAR_W:BP_VAR_R;
-       zval *dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
-
+       zval *dim;
+       
+       if (IS_CV == IS_UNUSED && type == BP_VAR_R) {
+               zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
+       }
+       dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
        zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, type TSRMLS_CC);
 
        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -20424,8 +20469,12 @@ static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG
        zend_op *opline = EX(opline);
        
        int type = ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)?BP_VAR_W:BP_VAR_R;
-       zval *dim = &opline->op2.u.constant;
-
+       zval *dim;
+       
+       if (IS_CONST == IS_UNUSED && type == BP_VAR_R) {
+               zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
+       }
+       dim = &opline->op2.u.constant;
        zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), type TSRMLS_CC), dim, 0, type TSRMLS_CC);
 
 
@@ -21832,8 +21881,12 @@ static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zend_op *opline = EX(opline);
        zend_free_op free_op2;
        int type = ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)?BP_VAR_W:BP_VAR_R;
-       zval *dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
-
+       zval *dim;
+       
+       if (IS_TMP_VAR == IS_UNUSED && type == BP_VAR_R) {
+               zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
+       }
+       dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
        zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), type TSRMLS_CC), dim, 1, type TSRMLS_CC);
        zval_dtor(free_op2.var);
 
@@ -23243,8 +23296,12 @@ static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zend_op *opline = EX(opline);
        zend_free_op free_op2;
        int type = ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)?BP_VAR_W:BP_VAR_R;
-       zval *dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
-
+       zval *dim;
+       
+       if (IS_VAR == IS_UNUSED && type == BP_VAR_R) {
+               zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
+       }
+       dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
        zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), type TSRMLS_CC), dim, 0, type TSRMLS_CC);
        if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
 
@@ -24229,6 +24286,35 @@ static int ZEND_FETCH_DIM_W_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        ZEND_VM_NEXT_OPCODE();
 }
 
+static int ZEND_FETCH_DIM_RW_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+       zend_op *opline = EX(opline);
+       
+       zval *dim = NULL;
+
+       zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC), dim, 0, BP_VAR_RW TSRMLS_CC);
+
+
+       ZEND_VM_NEXT_OPCODE();
+}
+
+static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+       zend_op *opline = EX(opline);
+       
+       int type = ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)?BP_VAR_W:BP_VAR_R;
+       zval *dim;
+       
+       if (IS_UNUSED == IS_UNUSED && type == BP_VAR_R) {
+               zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
+       }
+       dim = NULL;
+       zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), type TSRMLS_CC), dim, 0, type TSRMLS_CC);
+
+
+       ZEND_VM_NEXT_OPCODE();
+}
+
 static int ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        zend_op *opline = EX(opline);
@@ -25068,8 +25154,12 @@ static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zend_op *opline = EX(opline);
        
        int type = ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)?BP_VAR_W:BP_VAR_R;
-       zval *dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
-
+       zval *dim;
+       
+       if (IS_CV == IS_UNUSED && type == BP_VAR_R) {
+               zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
+       }
+       dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
        zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), type TSRMLS_CC), dim, 0, type TSRMLS_CC);
 
 
@@ -27983,7 +28073,7 @@ void zend_init_opcodes_handlers()
        ZEND_FETCH_DIM_RW_SPEC_VAR_CONST_HANDLER,
        ZEND_FETCH_DIM_RW_SPEC_VAR_TMP_HANDLER,
        ZEND_FETCH_DIM_RW_SPEC_VAR_VAR_HANDLER,
-       ZEND_NULL_HANDLER,
+       ZEND_FETCH_DIM_RW_SPEC_VAR_UNUSED_HANDLER,
        ZEND_FETCH_DIM_RW_SPEC_VAR_CV_HANDLER,
        ZEND_NULL_HANDLER,
        ZEND_NULL_HANDLER,
@@ -27993,7 +28083,7 @@ void zend_init_opcodes_handlers()
        ZEND_FETCH_DIM_RW_SPEC_CV_CONST_HANDLER,
        ZEND_FETCH_DIM_RW_SPEC_CV_TMP_HANDLER,
        ZEND_FETCH_DIM_RW_SPEC_CV_VAR_HANDLER,
-       ZEND_NULL_HANDLER,
+       ZEND_FETCH_DIM_RW_SPEC_CV_UNUSED_HANDLER,
        ZEND_FETCH_DIM_RW_SPEC_CV_CV_HANDLER,
        ZEND_NULL_HANDLER,
        ZEND_NULL_HANDLER,
@@ -28133,7 +28223,7 @@ void zend_init_opcodes_handlers()
        ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CONST_HANDLER,
        ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMP_HANDLER,
        ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_VAR_HANDLER,
-       ZEND_NULL_HANDLER,
+       ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_UNUSED_HANDLER,
        ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CV_HANDLER,
        ZEND_NULL_HANDLER,
        ZEND_NULL_HANDLER,
@@ -28143,7 +28233,7 @@ void zend_init_opcodes_handlers()
        ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CONST_HANDLER,
        ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMP_HANDLER,
        ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_VAR_HANDLER,
-       ZEND_NULL_HANDLER,
+       ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNUSED_HANDLER,
        ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CV_HANDLER,
        ZEND_NULL_HANDLER,
        ZEND_NULL_HANDLER,