From f85c818fe870512a49a0c2885938c946c811270d Mon Sep 17 00:00:00 2001 From: Andi Gutmans Date: Wed, 26 Dec 2001 14:46:18 +0000 Subject: [PATCH] - Start fixing the parsing rules so that function and method calls - can't be used in a write context. --- Zend/zend_compile.c | 16 ++++++++-------- Zend/zend_language_parser.y | 28 ++++++++++++++-------------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 81c4e25fd3..c37dafc79a 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -545,18 +545,16 @@ void zend_check_writable_variable(znode *variable) if (type & ZEND_PARSED_METHOD_CALL) { zend_error(E_ERROR, "Can't use method return value in write context"); } - if ((type & ZEND_PARSED_FUNCTION_CALL) && - !(type & (ZEND_PARSED_METHOD_CALL|ZEND_PARSED_MEMBER))) { + if (type == ZEND_PARSED_FUNCTION_CALL) { zend_error(E_ERROR, "Can't use function return value in write context"); } } -zend_bool zend_variable_buffer_empty(TSRMLS_D) +zend_bool zend_is_function_or_method_call(znode *variable) { - zend_llist *fetch_list_ptr; + zend_uint type = variable->u.EA.type; - zend_stack_top(&CG(bp_stack), (void **) &fetch_list_ptr); - return !fetch_list_ptr->head; + return ((type & ZEND_PARSED_METHOD_CALL) || (type == ZEND_PARSED_FUNCTION_CALL)); } @@ -1069,7 +1067,7 @@ void zend_do_pass_param(znode *param, int op, int offset TSRMLS_DC) send_by_reference = ARG_SHOULD_BE_SENT_BY_REF(offset, 1, arg_types)?ZEND_ARG_SEND_BY_REF:0; - if (op == ZEND_SEND_VAR && zend_variable_buffer_empty(TSRMLS_C)) { + if (op == ZEND_SEND_VAR && zend_is_function_or_method_call(param)) { /* Method call */ op = ZEND_SEND_VAR_NO_REF; } else if (op == ZEND_SEND_VAL && param->op_type == IS_VAR) { @@ -2372,6 +2370,8 @@ void zend_do_isset_or_isempty(int type, znode *result, znode *variable TSRMLS_DC zend_op *opline; zend_do_end_variable_parse(BP_VAR_IS, 0 TSRMLS_CC); + zend_check_writable_variable(variable); + opline = get_next_op(CG(active_op_array) TSRMLS_CC); opline->opcode = ZEND_ISSET_ISEMPTY; @@ -2390,7 +2390,7 @@ void zend_do_foreach_begin(znode *foreach_token, znode *array, znode *open_brack zend_bool is_variable; if (variable) { - if (zend_variable_buffer_empty(TSRMLS_C)) { + if (zend_is_function_or_method_call(array)) { is_variable = 0; } else { is_variable = 1; diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index e8fb34b7a5..377c185f3a 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -440,21 +440,21 @@ non_empty_for_expr: expr_without_variable: T_LIST '(' { zend_do_list_init(TSRMLS_C); } assignment_list ')' '=' expr { zend_do_list_end(&$$, &$7 TSRMLS_CC); } - | cvar '=' expr { zend_do_end_variable_parse(BP_VAR_W, 0 TSRMLS_CC); zend_do_assign(&$$, &$1, &$3 TSRMLS_CC); } - | cvar '=' '&' w_cvar { zend_do_end_variable_parse(BP_VAR_W, 0 TSRMLS_CC); zend_do_assign_ref(&$$, &$1, &$4 TSRMLS_CC); } - | cvar '=' '&' T_NEW new_class_entry { zend_do_extended_fcall_begin(TSRMLS_C); zend_do_begin_new_object(&$4, &$5 TSRMLS_CC); } ctor_arguments { zend_do_end_new_object(&$3, &$4, &$7 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C); zend_do_end_variable_parse(BP_VAR_W, 0 TSRMLS_CC); zend_do_assign_ref(&$$, &$1, &$3 TSRMLS_CC); } + | cvar '=' expr { zend_check_writable_variable(&$$); zend_do_end_variable_parse(BP_VAR_W, 0 TSRMLS_CC); zend_do_assign(&$$, &$1, &$3 TSRMLS_CC); } + | cvar '=' '&' w_cvar { zend_check_writable_variable(&$$); zend_do_end_variable_parse(BP_VAR_W, 0 TSRMLS_CC); zend_do_assign_ref(&$$, &$1, &$4 TSRMLS_CC); } + | cvar '=' '&' T_NEW new_class_entry { zend_check_writable_variable(&$$); zend_do_extended_fcall_begin(TSRMLS_C); zend_do_begin_new_object(&$4, &$5 TSRMLS_CC); } ctor_arguments { zend_do_end_new_object(&$3, &$4, &$7 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C); zend_do_end_variable_parse(BP_VAR_W, 0 TSRMLS_CC); zend_do_assign_ref(&$$, &$1, &$3 TSRMLS_CC); } | T_NEW new_class_entry { zend_do_extended_fcall_begin(TSRMLS_C); zend_do_begin_new_object(&$1, &$2 TSRMLS_CC); } ctor_arguments { zend_do_end_new_object(&$$, &$1, &$4 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);} - | cvar T_PLUS_EQUAL expr { zend_do_end_variable_parse(BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_ADD, &$$, &$1, &$3 TSRMLS_CC); } - | cvar T_MINUS_EQUAL expr { zend_do_end_variable_parse(BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_SUB, &$$, &$1, &$3 TSRMLS_CC); } - | cvar T_MUL_EQUAL expr { zend_do_end_variable_parse(BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_MUL, &$$, &$1, &$3 TSRMLS_CC); } - | cvar T_DIV_EQUAL expr { zend_do_end_variable_parse(BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_DIV, &$$, &$1, &$3 TSRMLS_CC); } - | cvar T_CONCAT_EQUAL expr { zend_do_end_variable_parse(BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_CONCAT, &$$, &$1, &$3 TSRMLS_CC); } - | cvar T_MOD_EQUAL expr { zend_do_end_variable_parse(BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_MOD, &$$, &$1, &$3 TSRMLS_CC); } - | cvar T_AND_EQUAL expr { zend_do_end_variable_parse(BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_BW_AND, &$$, &$1, &$3 TSRMLS_CC); } - | cvar T_OR_EQUAL expr { zend_do_end_variable_parse(BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_BW_OR, &$$, &$1, &$3 TSRMLS_CC); } - | cvar T_XOR_EQUAL expr { zend_do_end_variable_parse(BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_BW_XOR, &$$, &$1, &$3 TSRMLS_CC); } - | cvar T_SL_EQUAL expr { zend_do_end_variable_parse(BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_SL, &$$, &$1, &$3 TSRMLS_CC); } - | cvar T_SR_EQUAL expr { zend_do_end_variable_parse(BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_SR, &$$, &$1, &$3 TSRMLS_CC); } + | cvar T_PLUS_EQUAL expr { zend_check_writable_variable(&$$); zend_do_end_variable_parse(BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_ADD, &$$, &$1, &$3 TSRMLS_CC); } + | cvar T_MINUS_EQUAL expr { zend_check_writable_variable(&$$); zend_do_end_variable_parse(BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_SUB, &$$, &$1, &$3 TSRMLS_CC); } + | cvar T_MUL_EQUAL expr { zend_check_writable_variable(&$$); zend_do_end_variable_parse(BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_MUL, &$$, &$1, &$3 TSRMLS_CC); } + | cvar T_DIV_EQUAL expr { zend_check_writable_variable(&$$); zend_do_end_variable_parse(BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_DIV, &$$, &$1, &$3 TSRMLS_CC); } + | cvar T_CONCAT_EQUAL expr { zend_check_writable_variable(&$$); zend_do_end_variable_parse(BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_CONCAT, &$$, &$1, &$3 TSRMLS_CC); } + | cvar T_MOD_EQUAL expr { zend_check_writable_variable(&$$); zend_do_end_variable_parse(BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_MOD, &$$, &$1, &$3 TSRMLS_CC); } + | cvar T_AND_EQUAL expr { zend_check_writable_variable(&$$); zend_do_end_variable_parse(BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_BW_AND, &$$, &$1, &$3 TSRMLS_CC); } + | cvar T_OR_EQUAL expr { zend_check_writable_variable(&$$); zend_do_end_variable_parse(BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_BW_OR, &$$, &$1, &$3 TSRMLS_CC); } + | cvar T_XOR_EQUAL expr { zend_check_writable_variable(&$$); zend_do_end_variable_parse(BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_BW_XOR, &$$, &$1, &$3 TSRMLS_CC); } + | cvar T_SL_EQUAL expr { zend_check_writable_variable(&$$); zend_do_end_variable_parse(BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_SL, &$$, &$1, &$3 TSRMLS_CC); } + | cvar T_SR_EQUAL expr { zend_check_writable_variable(&$$); zend_do_end_variable_parse(BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_SR, &$$, &$1, &$3 TSRMLS_CC); } | rw_cvar T_INC { zend_do_post_incdec(&$$, &$1, ZEND_POST_INC TSRMLS_CC); } | T_INC rw_cvar { zend_do_pre_incdec(&$$, &$2, ZEND_PRE_INC TSRMLS_CC); } | rw_cvar T_DEC { zend_do_post_incdec(&$$, &$1, ZEND_POST_DEC TSRMLS_CC); } -- 2.40.0