]> granicus.if.org Git - php/commitdiff
Removed undocumnted and incomplete support for strings in list() operator
authorDmitry Stogov <dmitry@php.net>
Tue, 3 Apr 2007 06:33:00 +0000 (06:33 +0000)
committerDmitry Stogov <dmitry@php.net>
Tue, 3 Apr 2007 06:33:00 +0000 (06:33 +0000)
NEWS
Zend/zend_compile.c
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

diff --git a/NEWS b/NEWS
index b406b71ec7a1557cb7467407052d9ddb53ff363b..b5c1f647e5d15fcdfef64530c9716e3c2eb9c705 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -13,6 +13,8 @@ PHP                                                                        NEWS
 - Changed allow_url_fopen/allow_url_include to allow
   per-wrapper enable/disable and runtime tightening. (Sara)
 
+- Removed undocumnted and incomplete support for strings in list() operator.
+  (Dmitry)
 - Removed old legacy:
   . "register_globals" support. (Pierre)
   . "register_long_arrays" ini option. (Dmitry)
index 0bd9586c64b66a55fc59a8fa7b822511fcc2277a..4191d059a618ff79911762c1e18739db9e8c1abb 100644 (file)
@@ -1071,13 +1071,18 @@ void zend_do_free(znode *op1 TSRMLS_DC)
                        opline->result.u.EA.type |= EXT_TYPE_UNUSED;
                } else {
                        while (opline>CG(active_op_array)->opcodes) {
-                               if (opline->opcode == ZEND_FETCH_DIM_R
+                               if (opline->opcode == ZEND_FETCH_DIM_TMP_VAR
                                    && opline->op1.op_type == IS_VAR
                                    && opline->op1.u.var == op1->u.var) {
                                        /* This should the end of a list() construct
                                         * Mark its result as unused
                                         */
-                                       opline->extended_value = ZEND_FETCH_STANDARD;
+                                       opline = get_next_op(CG(active_op_array) TSRMLS_CC);
+
+                                       opline->opcode = ZEND_SWITCH_FREE;
+                                       opline->extended_value = 0;
+                                       opline->op1 = *op1;
+                                       SET_UNUSED(opline->op2);
                                        break;
                                } else if (opline->result.op_type==IS_VAR
                                        && opline->result.u.var == op1->u.var) {
@@ -3633,8 +3638,6 @@ void zend_do_list_end(znode *result, znode *expr TSRMLS_DC)
        zend_llist_element *dimension;
        zend_op *opline;
        znode last_container;
-       int last_op_number;
-       zend_op *last_op;
 
        le = CG(list_llist).head;
        while (le) {
@@ -3644,20 +3647,10 @@ void zend_do_list_end(znode *result, znode *expr TSRMLS_DC)
                        opline = get_next_op(CG(active_op_array) TSRMLS_CC);
                        if (dimension == tmp_dimension_llist->head) { /* first */
                                last_container = *expr;
-                               switch (expr->op_type) {
-                                       case IS_VAR:
-                                       case IS_CV:
-                                               opline->opcode = ZEND_FETCH_DIM_R;
-                                               break;
-                                       case IS_TMP_VAR:
-                                               opline->opcode = ZEND_FETCH_DIM_TMP_VAR;
-                                               break;
-                                       case IS_CONST: /* fetch_dim_tmp_var will handle this bogus fetch */
-                                               zval_copy_ctor(&expr->u.constant);
-                                               opline->opcode = ZEND_FETCH_DIM_TMP_VAR;
-                                               break;
+                               opline->opcode = ZEND_FETCH_DIM_TMP_VAR;
+                               if (expr->op_type == IS_CONST) {
+                                       zval_copy_ctor(&expr->u.constant);
                                }
-                               opline->extended_value = ZEND_FETCH_ADD_LOCK;
                        } else {
                                opline->opcode = ZEND_FETCH_DIM_R;
                        }
@@ -3675,8 +3668,6 @@ void zend_do_list_end(znode *result, znode *expr TSRMLS_DC)
                ((list_llist_element *) le->data)->value = last_container;
                zend_llist_destroy(&((list_llist_element *) le->data)->dimensions);
                zend_do_end_variable_parse(BP_VAR_W, 0 TSRMLS_CC);
-               last_op_number = get_next_op_number(CG(active_op_array))-1;
-               last_op = &CG(active_op_array)->opcodes[last_op_number];
                zend_do_assign(result, &((list_llist_element *) le->data)->var, &((list_llist_element *) le->data)->value TSRMLS_CC);
                zend_do_free(result TSRMLS_CC);
                le = le->next;
index 71e79f3948e3b24a7fad94f2dda2a340bde55f12..f8ce0c186a4eac243aa22575097dbbe92b4a1f15 100644 (file)
@@ -1074,11 +1074,14 @@ ZEND_VM_HANDLER(81, ZEND_FETCH_DIM_R, VAR|CV, CONST|TMP|VAR|CV)
        zend_free_op free_op1, free_op2;
        zval *dim = GET_OP2_ZVAL_PTR(BP_VAR_R);
 
+       /* No longer needed
        if (opline->extended_value == ZEND_FETCH_ADD_LOCK &&
            OP1_TYPE != IS_CV &&
            EX_T(opline->op1.u.var).var.ptr_ptr) {
                PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
        }
+       */
+
        zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), GET_OP1_ZVAL_PTR_PTR(BP_VAR_R), dim, IS_OP2_TMP_FREE(), BP_VAR_R TSRMLS_CC);
        FREE_OP2();
        FREE_OP1_VAR_PTR();
@@ -1383,12 +1386,16 @@ ZEND_VM_HANDLER(97, ZEND_FETCH_OBJ_UNSET, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
        ZEND_VM_NEXT_OPCODE();
 }
 
-ZEND_VM_HANDLER(98, ZEND_FETCH_DIM_TMP_VAR, CONST|TMP, CONST)
+ZEND_VM_HANDLER(98, ZEND_FETCH_DIM_TMP_VAR, VAR|CV|CONST|TMP, CONST)
 {
        zend_op *opline = EX(opline);
        zend_free_op free_op1;
-       zval *container = GET_OP1_ZVAL_PTR(BP_VAR_R);
-
+       zval *container;
+       
+       if (OP1_TYPE == IS_VAR && EX_T(opline->op1.u.var).var.ptr == NULL) {
+               zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
+       }
+       container = GET_OP1_ZVAL_PTR(BP_VAR_R);
        if (Z_TYPE_P(container) != IS_ARRAY) {
                if (!RETURN_VALUE_UNUSED(&opline->result)) {
                        EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
index 04ccda6a560eabc886142ed801f3875b1eb2c6de..3f757c3c1b239ca25f4e64ed3ca2ee165a3acd29 100644 (file)
@@ -2669,8 +2669,12 @@ static int ZEND_FETCH_DIM_TMP_VAR_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_A
 {
        zend_op *opline = EX(opline);
 
-       zval *container = &opline->op1.u.constant;
+       zval *container;
 
+       if (IS_CONST == IS_VAR && EX_T(opline->op1.u.var).var.ptr == NULL) {
+               zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
+       }
+       container = &opline->op1.u.constant;
        if (Z_TYPE_P(container) != IS_ARRAY) {
                if (!RETURN_VALUE_UNUSED(&opline->result)) {
                        EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
@@ -5367,8 +5371,12 @@ static int ZEND_FETCH_DIM_TMP_VAR_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG
 {
        zend_op *opline = EX(opline);
        zend_free_op free_op1;
-       zval *container = _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
+       zval *container;
 
+       if (IS_TMP_VAR == IS_VAR && EX_T(opline->op1.u.var).var.ptr == NULL) {
+               zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
+       }
+       container = _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
        if (Z_TYPE_P(container) != IS_ARRAY) {
                if (!RETURN_VALUE_UNUSED(&opline->result)) {
                        EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
@@ -9201,11 +9209,14 @@ static int ZEND_FETCH_DIM_R_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zend_free_op free_op1;
        zval *dim = &opline->op2.u.constant;
 
+       /* No longer needed
        if (opline->extended_value == ZEND_FETCH_ADD_LOCK &&
            IS_VAR != IS_CV &&
            EX_T(opline->op1.u.var).var.ptr_ptr) {
                PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
        }
+       */
+
        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_R TSRMLS_CC);
 
        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -9510,6 +9521,33 @@ static int ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        ZEND_VM_NEXT_OPCODE();
 }
 
+static int ZEND_FETCH_DIM_TMP_VAR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+       zend_op *opline = EX(opline);
+       zend_free_op free_op1;
+       zval *container;
+
+       if (IS_VAR == IS_VAR && EX_T(opline->op1.u.var).var.ptr == NULL) {
+               zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
+       }
+       container = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
+       if (Z_TYPE_P(container) != IS_ARRAY) {
+               if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                       EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
+                       PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
+               }
+       } else {
+
+               zval *dim = &opline->op2.u.constant;
+
+               EX_T(opline->result.u.var).var.ptr_ptr = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, BP_VAR_R TSRMLS_CC);
+               SELECTIVE_PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr, &opline->result);
+
+       }
+       AI_USE_PTR(EX_T(opline->result.u.var).var);
+       ZEND_VM_NEXT_OPCODE();
+}
+
 static int ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        zend_op *opline = EX(opline);
@@ -10740,11 +10778,14 @@ static int ZEND_FETCH_DIM_R_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zend_free_op free_op1, free_op2;
        zval *dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
 
+       /* No longer needed
        if (opline->extended_value == ZEND_FETCH_ADD_LOCK &&
            IS_VAR != IS_CV &&
            EX_T(opline->op1.u.var).var.ptr_ptr) {
                PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
        }
+       */
+
        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, BP_VAR_R TSRMLS_CC);
        zval_dtor(free_op2.var);
        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -12282,11 +12323,14 @@ static int ZEND_FETCH_DIM_R_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zend_free_op free_op1, free_op2;
        zval *dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
 
+       /* No longer needed
        if (opline->extended_value == ZEND_FETCH_ADD_LOCK &&
            IS_VAR != IS_CV &&
            EX_T(opline->op1.u.var).var.ptr_ptr) {
                PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
        }
+       */
+
        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_R TSRMLS_CC);
        if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -14297,11 +14341,14 @@ static int ZEND_FETCH_DIM_R_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zend_free_op free_op1;
        zval *dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
 
+       /* No longer needed
        if (opline->extended_value == ZEND_FETCH_ADD_LOCK &&
            IS_VAR != IS_CV &&
            EX_T(opline->op1.u.var).var.ptr_ptr) {
                PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
        }
+       */
+
        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_R TSRMLS_CC);
 
        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -21647,11 +21694,14 @@ static int ZEND_FETCH_DIM_R_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 
        zval *dim = &opline->op2.u.constant;
 
+       /* No longer needed
        if (opline->extended_value == ZEND_FETCH_ADD_LOCK &&
            IS_CV != IS_CV &&
            EX_T(opline->op1.u.var).var.ptr_ptr) {
                PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
        }
+       */
+
        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_R TSRMLS_CC), dim, 0, BP_VAR_R TSRMLS_CC);
 
 
@@ -21954,6 +22004,33 @@ static int ZEND_FETCH_OBJ_UNSET_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        ZEND_VM_NEXT_OPCODE();
 }
 
+static int ZEND_FETCH_DIM_TMP_VAR_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+       zend_op *opline = EX(opline);
+
+       zval *container;
+
+       if (IS_CV == IS_VAR && EX_T(opline->op1.u.var).var.ptr == NULL) {
+               zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
+       }
+       container = _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);
+       if (Z_TYPE_P(container) != IS_ARRAY) {
+               if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                       EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
+                       PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
+               }
+       } else {
+
+               zval *dim = &opline->op2.u.constant;
+
+               EX_T(opline->result.u.var).var.ptr_ptr = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, BP_VAR_R TSRMLS_CC);
+               SELECTIVE_PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr, &opline->result);
+
+       }
+       AI_USE_PTR(EX_T(opline->result.u.var).var);
+       ZEND_VM_NEXT_OPCODE();
+}
+
 static int ZEND_ASSIGN_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        zend_op *opline = EX(opline);
@@ -23178,11 +23255,14 @@ static int ZEND_FETCH_DIM_R_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zend_free_op free_op2;
        zval *dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
 
+       /* No longer needed
        if (opline->extended_value == ZEND_FETCH_ADD_LOCK &&
            IS_CV != IS_CV &&
            EX_T(opline->op1.u.var).var.ptr_ptr) {
                PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
        }
+       */
+
        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_R TSRMLS_CC), dim, 1, BP_VAR_R TSRMLS_CC);
        zval_dtor(free_op2.var);
 
@@ -24712,11 +24792,14 @@ static int ZEND_FETCH_DIM_R_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zend_free_op free_op2;
        zval *dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
 
+       /* No longer needed
        if (opline->extended_value == ZEND_FETCH_ADD_LOCK &&
            IS_CV != IS_CV &&
            EX_T(opline->op1.u.var).var.ptr_ptr) {
                PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
        }
+       */
+
        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_R TSRMLS_CC), dim, 0, BP_VAR_R TSRMLS_CC);
        if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
 
@@ -26717,11 +26800,14 @@ static int ZEND_FETCH_DIM_R_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 
        zval *dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
 
+       /* No longer needed
        if (opline->extended_value == ZEND_FETCH_ADD_LOCK &&
            IS_CV != IS_CV &&
            EX_T(opline->op1.u.var).var.ptr_ptr) {
                PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
        }
+       */
+
        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_R TSRMLS_CC), dim, 0, BP_VAR_R TSRMLS_CC);
 
 
@@ -30077,6 +30163,7 @@ void zend_init_opcodes_handlers()
        ZEND_NULL_HANDLER,
        ZEND_NULL_HANDLER,
        ZEND_NULL_HANDLER,
+       ZEND_FETCH_DIM_TMP_VAR_SPEC_VAR_CONST_HANDLER,
        ZEND_NULL_HANDLER,
        ZEND_NULL_HANDLER,
        ZEND_NULL_HANDLER,
@@ -30086,8 +30173,7 @@ void zend_init_opcodes_handlers()
        ZEND_NULL_HANDLER,
        ZEND_NULL_HANDLER,
        ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
+       ZEND_FETCH_DIM_TMP_VAR_SPEC_CV_CONST_HANDLER,
        ZEND_NULL_HANDLER,
        ZEND_NULL_HANDLER,
        ZEND_NULL_HANDLER,