From af1ed8027437ad60c9265ca1b2006a4069243353 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 12 May 2008 09:09:05 +0000 Subject: [PATCH] Fixed bug #44952 (isset() does not checks correctly variable variable) --- Zend/zend_compile.c | 5 ++++- Zend/zend_compile.h | 2 ++ Zend/zend_vm_def.h | 10 +++++----- Zend/zend_vm_execute.h | 40 ++++++++++++++++++++-------------------- 4 files changed, 31 insertions(+), 26 deletions(-) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 26e32c5dd3..19fc541a05 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -4187,6 +4187,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]; @@ -4221,6 +4222,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]; @@ -4235,9 +4237,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; } diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index dc2dff1a7f..d1faf2509c 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -664,6 +664,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) diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 734fccec74..d3c7559413 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -3159,7 +3159,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); @@ -3196,7 +3196,7 @@ ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMP|VAR|CV, ANY) zval_copy_ctor(&tmp); convert_to_string(&tmp); varname = &tmp; - } else if (OP1_TYPE == IS_VAR) { + } else if (OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) { Z_ADDREF_P(varname); } @@ -3229,7 +3229,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(); @@ -3666,7 +3666,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)) { @@ -3710,7 +3710,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; diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index d08b0adc66..5d31681721 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -1788,7 +1788,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); @@ -1825,7 +1825,7 @@ static int ZEND_UNSET_VAR_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zval_copy_ctor(&tmp); convert_to_string(&tmp); varname = &tmp; - } else if (IS_CONST == IS_VAR) { + } else if (IS_CONST == IS_VAR || IS_CONST == IS_CV) { Z_ADDREF_P(varname); } @@ -1858,7 +1858,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); } @@ -2023,7 +2023,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)) { @@ -2067,7 +2067,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; @@ -5001,7 +5001,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); @@ -5038,7 +5038,7 @@ static int ZEND_UNSET_VAR_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zval_copy_ctor(&tmp); convert_to_string(&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); } @@ -5071,7 +5071,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); @@ -5236,7 +5236,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)) { @@ -5280,7 +5280,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; @@ -8252,7 +8252,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); @@ -8289,7 +8289,7 @@ static int ZEND_UNSET_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zval_copy_ctor(&tmp); convert_to_string(&tmp); varname = &tmp; - } else if (IS_VAR == IS_VAR) { + } else if (IS_VAR == IS_VAR || IS_VAR == IS_CV) { Z_ADDREF_P(varname); } @@ -8322,7 +8322,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);}; @@ -8633,7 +8633,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)) { @@ -8677,7 +8677,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; @@ -21967,7 +21967,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); @@ -22004,7 +22004,7 @@ static int ZEND_UNSET_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zval_copy_ctor(&tmp); convert_to_string(&tmp); varname = &tmp; - } else if (IS_CV == IS_VAR) { + } else if (IS_CV == IS_VAR || IS_CV == IS_CV) { Z_ADDREF_P(varname); } @@ -22037,7 +22037,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); } @@ -22202,7 +22202,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)) { @@ -22246,7 +22246,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; -- 2.40.0