]> granicus.if.org Git - php/commitdiff
Fixed bug #44952 (isset() does not checks correctly variable variable)
authorDmitry Stogov <dmitry@php.net>
Mon, 12 May 2008 09:09:28 +0000 (09:09 +0000)
committerDmitry Stogov <dmitry@php.net>
Mon, 12 May 2008 09:09:28 +0000 (09:09 +0000)
Zend/zend_compile.c
Zend/zend_compile.h
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

index b090bc6d9e399385ec034cc1f443226d37eb2d4a..c5f46469b75d41107aeaa74d8c37c72e9204d605 100644 (file)
@@ -4442,6 +4442,7 @@ void zend_do_unset(znode *variable TSRMLS_DC) /* {{{ */
                SET_UNUSED(opline->op2);
                opline->op2.u.EA.type = ZEND_FETCH_LOCAL;
                SET_UNUSED(opline->result);
+               opline->extended_value = ZEND_QUICK_SET;
        } else {
                last_op = &CG(active_op_array)->opcodes[get_next_op_number(CG(active_op_array))-1];
 
@@ -4476,6 +4477,7 @@ void zend_do_isset_or_isempty(int type, znode *result, znode *variable TSRMLS_DC
                SET_UNUSED(last_op->op2);
                last_op->op2.u.EA.type = ZEND_FETCH_LOCAL;
                last_op->result.u.var = get_temporary_variable(CG(active_op_array));
+               last_op->extended_value = ZEND_QUICK_SET;
        } else {
                last_op = &CG(active_op_array)->opcodes[get_next_op_number(CG(active_op_array))-1];
 
@@ -4490,9 +4492,10 @@ void zend_do_isset_or_isempty(int type, znode *result, znode *variable TSRMLS_DC
                                last_op->opcode = ZEND_ISSET_ISEMPTY_PROP_OBJ;
                                break;
                }
+               last_op->extended_value = 0;
        }
        last_op->result.op_type = IS_TMP_VAR;
-       last_op->extended_value = type;
+       last_op->extended_value |= type;
 
        *result = last_op->result;
 }
index 1c1ed444eeb62853bdf0aac9e514b88a7e31d301..675018413b10ffc23ccd2a95638c30c7d50a24a3 100644 (file)
@@ -691,6 +691,8 @@ int zendlex(znode *zendlval TSRMLS_DC);
 
 #define ZEND_ISSET                             (1<<0)
 #define ZEND_ISEMPTY                   (1<<1)
+#define ZEND_ISSET_ISEMPTY_MASK        (ZEND_ISSET | ZEND_ISEMPTY)
+#define ZEND_QUICK_SET                 (1<<2)
 
 #define ZEND_CT        (1<<0)
 #define ZEND_RT (1<<1)
index 6ee4697ac943cb0c2b2b3970538f93b4ac257ca3..446a7a881e146ef16c5bb83ee814165bd64a42b8 100644 (file)
@@ -3258,7 +3258,7 @@ ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMP|VAR|CV, ANY)
        HashTable *target_symbol_table;
        zend_free_op free_op1;
 
-       if (OP1_TYPE == IS_CV) {
+       if (OP1_TYPE == IS_CV && (opline->extended_value & ZEND_QUICK_SET)) {
                if (EG(active_symbol_table)) {
                        zend_execute_data *ex = EX(prev_execute_data);
                        zend_compiled_variable *cv = &CV_DEF_OF(opline->op1.u.var);
@@ -3295,7 +3295,7 @@ ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMP|VAR|CV, ANY)
                zval_copy_ctor(&tmp);
                convert_to_text(&tmp);
                varname = &tmp;
-       } else if (OP1_TYPE == IS_VAR) {
+       } else if (OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) {
                Z_ADDREF_P(varname);
        }
 
@@ -3332,7 +3332,7 @@ ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMP|VAR|CV, ANY)
 
        if (varname == &tmp) {
                zval_dtor(&tmp);
-       } else if (OP1_TYPE == IS_VAR) {
+       } else if (OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) {
                zval_ptr_dtor(&varname);
        }
        FREE_OP1();
@@ -3802,7 +3802,7 @@ ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_VAR, CONST|TMP|VAR|CV, ANY)
        zval **value;
        zend_bool isset = 1;
 
-       if (OP1_TYPE == IS_CV) {
+       if (OP1_TYPE == IS_CV && (opline->extended_value & ZEND_QUICK_SET)) {
                if (EX(CVs)[opline->op1.u.var]) {
                        value = EX(CVs)[opline->op1.u.var];
                } else if (EG(active_symbol_table)) {
@@ -3846,7 +3846,7 @@ ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_VAR, CONST|TMP|VAR|CV, ANY)
 
        Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;
 
-       switch (opline->extended_value) {
+       switch (opline->extended_value & ZEND_ISSET_ISEMPTY_MASK) {
                case ZEND_ISSET:
                        if (isset && Z_TYPE_PP(value) == IS_NULL) {
                                Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 0;
index 56dbeedab79fd5829e4f62268177d7bd224fdae6..ea2dcdbcbce0ac548c7f648a89842f89fab424a9 100644 (file)
@@ -1819,7 +1819,7 @@ static int ZEND_UNSET_VAR_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        HashTable *target_symbol_table;
 
 
-       if (IS_CONST == IS_CV) {
+       if (IS_CONST == IS_CV && (opline->extended_value & ZEND_QUICK_SET)) {
                if (EG(active_symbol_table)) {
                        zend_execute_data *ex = EX(prev_execute_data);
                        zend_compiled_variable *cv = &CV_DEF_OF(opline->op1.u.var);
@@ -1856,7 +1856,7 @@ static int ZEND_UNSET_VAR_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                zval_copy_ctor(&tmp);
                convert_to_text(&tmp);
                varname = &tmp;
-       } else if (IS_CONST == IS_VAR) {
+       } else if (IS_CONST == IS_VAR || IS_CONST == IS_CV) {
                Z_ADDREF_P(varname);
        }
 
@@ -1893,7 +1893,7 @@ static int ZEND_UNSET_VAR_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 
        if (varname == &tmp) {
                zval_dtor(&tmp);
-       } else if (IS_CONST == IS_VAR) {
+       } else if (IS_CONST == IS_VAR || IS_CONST == IS_CV) {
                zval_ptr_dtor(&varname);
        }
 
@@ -2058,7 +2058,7 @@ static int ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zval **value;
        zend_bool isset = 1;
 
-       if (IS_CONST == IS_CV) {
+       if (IS_CONST == IS_CV && (opline->extended_value & ZEND_QUICK_SET)) {
                if (EX(CVs)[opline->op1.u.var]) {
                        value = EX(CVs)[opline->op1.u.var];
                } else if (EG(active_symbol_table)) {
@@ -2102,7 +2102,7 @@ static int ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 
        Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;
 
-       switch (opline->extended_value) {
+       switch (opline->extended_value & ZEND_ISSET_ISEMPTY_MASK) {
                case ZEND_ISSET:
                        if (isset && Z_TYPE_PP(value) == IS_NULL) {
                                Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 0;
@@ -5172,7 +5172,7 @@ static int ZEND_UNSET_VAR_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        HashTable *target_symbol_table;
        zend_free_op free_op1;
 
-       if (IS_TMP_VAR == IS_CV) {
+       if (IS_TMP_VAR == IS_CV && (opline->extended_value & ZEND_QUICK_SET)) {
                if (EG(active_symbol_table)) {
                        zend_execute_data *ex = EX(prev_execute_data);
                        zend_compiled_variable *cv = &CV_DEF_OF(opline->op1.u.var);
@@ -5209,7 +5209,7 @@ static int ZEND_UNSET_VAR_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                zval_copy_ctor(&tmp);
                convert_to_text(&tmp);
                varname = &tmp;
-       } else if (IS_TMP_VAR == IS_VAR) {
+       } else if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) {
                Z_ADDREF_P(varname);
        }
 
@@ -5246,7 +5246,7 @@ static int ZEND_UNSET_VAR_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 
        if (varname == &tmp) {
                zval_dtor(&tmp);
-       } else if (IS_TMP_VAR == IS_VAR) {
+       } else if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) {
                zval_ptr_dtor(&varname);
        }
        zval_dtor(free_op1.var);
@@ -5411,7 +5411,7 @@ static int ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zval **value;
        zend_bool isset = 1;
 
-       if (IS_TMP_VAR == IS_CV) {
+       if (IS_TMP_VAR == IS_CV && (opline->extended_value & ZEND_QUICK_SET)) {
                if (EX(CVs)[opline->op1.u.var]) {
                        value = EX(CVs)[opline->op1.u.var];
                } else if (EG(active_symbol_table)) {
@@ -5455,7 +5455,7 @@ static int ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 
        Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;
 
-       switch (opline->extended_value) {
+       switch (opline->extended_value & ZEND_ISSET_ISEMPTY_MASK) {
                case ZEND_ISSET:
                        if (isset && Z_TYPE_PP(value) == IS_NULL) {
                                Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 0;
@@ -8566,7 +8566,7 @@ static int ZEND_UNSET_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        HashTable *target_symbol_table;
        zend_free_op free_op1;
 
-       if (IS_VAR == IS_CV) {
+       if (IS_VAR == IS_CV && (opline->extended_value & ZEND_QUICK_SET)) {
                if (EG(active_symbol_table)) {
                        zend_execute_data *ex = EX(prev_execute_data);
                        zend_compiled_variable *cv = &CV_DEF_OF(opline->op1.u.var);
@@ -8603,7 +8603,7 @@ static int ZEND_UNSET_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                zval_copy_ctor(&tmp);
                convert_to_text(&tmp);
                varname = &tmp;
-       } else if (IS_VAR == IS_VAR) {
+       } else if (IS_VAR == IS_VAR || IS_VAR == IS_CV) {
                Z_ADDREF_P(varname);
        }
 
@@ -8640,7 +8640,7 @@ static int ZEND_UNSET_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 
        if (varname == &tmp) {
                zval_dtor(&tmp);
-       } else if (IS_VAR == IS_VAR) {
+       } else if (IS_VAR == IS_VAR || IS_VAR == IS_CV) {
                zval_ptr_dtor(&varname);
        }
        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -8961,7 +8961,7 @@ static int ZEND_ISSET_ISEMPTY_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zval **value;
        zend_bool isset = 1;
 
-       if (IS_VAR == IS_CV) {
+       if (IS_VAR == IS_CV && (opline->extended_value & ZEND_QUICK_SET)) {
                if (EX(CVs)[opline->op1.u.var]) {
                        value = EX(CVs)[opline->op1.u.var];
                } else if (EG(active_symbol_table)) {
@@ -9005,7 +9005,7 @@ static int ZEND_ISSET_ISEMPTY_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 
        Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;
 
-       switch (opline->extended_value) {
+       switch (opline->extended_value & ZEND_ISSET_ISEMPTY_MASK) {
                case ZEND_ISSET:
                        if (isset && Z_TYPE_PP(value) == IS_NULL) {
                                Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 0;
@@ -22875,7 +22875,7 @@ static int ZEND_UNSET_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        HashTable *target_symbol_table;
 
 
-       if (IS_CV == IS_CV) {
+       if (IS_CV == IS_CV && (opline->extended_value & ZEND_QUICK_SET)) {
                if (EG(active_symbol_table)) {
                        zend_execute_data *ex = EX(prev_execute_data);
                        zend_compiled_variable *cv = &CV_DEF_OF(opline->op1.u.var);
@@ -22912,7 +22912,7 @@ static int ZEND_UNSET_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                zval_copy_ctor(&tmp);
                convert_to_text(&tmp);
                varname = &tmp;
-       } else if (IS_CV == IS_VAR) {
+       } else if (IS_CV == IS_VAR || IS_CV == IS_CV) {
                Z_ADDREF_P(varname);
        }
 
@@ -22949,7 +22949,7 @@ static int ZEND_UNSET_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 
        if (varname == &tmp) {
                zval_dtor(&tmp);
-       } else if (IS_CV == IS_VAR) {
+       } else if (IS_CV == IS_VAR || IS_CV == IS_CV) {
                zval_ptr_dtor(&varname);
        }
 
@@ -23114,7 +23114,7 @@ static int ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zval **value;
        zend_bool isset = 1;
 
-       if (IS_CV == IS_CV) {
+       if (IS_CV == IS_CV && (opline->extended_value & ZEND_QUICK_SET)) {
                if (EX(CVs)[opline->op1.u.var]) {
                        value = EX(CVs)[opline->op1.u.var];
                } else if (EG(active_symbol_table)) {
@@ -23158,7 +23158,7 @@ static int ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 
        Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;
 
-       switch (opline->extended_value) {
+       switch (opline->extended_value & ZEND_ISSET_ISEMPTY_MASK) {
                case ZEND_ISSET:
                        if (isset && Z_TYPE_PP(value) == IS_NULL) {
                                Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 0;