From: Andi Gutmans Date: Tue, 11 Jun 2002 17:33:53 +0000 (+0000) Subject: - Fix problem with assigning functions by reference. X-Git-Tag: php5_5_0~69 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b2015c5610f094c83283134f2df6632e2e68681d;p=php - Fix problem with assigning functions by reference. --- diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index abefc3ce1d..5e85195630 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1552,8 +1552,18 @@ binary_assign_op_addr_obj: } NEXT_OPCODE(); case ZEND_ASSIGN_REF: - zend_assign_to_variable_reference(&EX(opline)->result, get_zval_ptr_ptr(&EX(opline)->op1, EX(Ts), BP_VAR_W), get_zval_ptr_ptr(&EX(opline)->op2, EX(Ts), BP_VAR_W), EX(Ts) TSRMLS_CC); - NEXT_OPCODE(); + { + zval **value_ptr_ptr = get_zval_ptr_ptr(&EX(opline)->op2, EX(Ts), BP_VAR_W); + + if (value_ptr_ptr = &EX(Ts)[EX(opline)->op2.u.var].var.ptr) { + if (!(*value_ptr_ptr != &EG(uninitialized_zval) && (PZVAL_IS_REF(*value_ptr_ptr) || (*value_ptr_ptr)->refcount == 1))) + { + zend_error(E_ERROR, "Can't assign by reference non-referencable value!"); + } + } + zend_assign_to_variable_reference(&EX(opline)->result, get_zval_ptr_ptr(&EX(opline)->op1, EX(Ts), BP_VAR_W), value_ptr_ptr, EX(Ts) TSRMLS_CC); + NEXT_OPCODE(); + } case ZEND_JMP: #if DEBUG_ZEND>=2 printf("Jumping to %d\n", EX(opline)->op1.u.opline_num); diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index 17cd896db3..a6a6fc7a83 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -173,7 +173,6 @@ statement: unticked_statement { zend_do_ticks(TSRMLS_C); } ; - unticked_statement: '{' inner_statement_list '}' | T_IF '(' expr ')' { zend_do_if_cond(&$3, &$4 TSRMLS_CC); } statement { zend_do_if_after_statement(&$4, 1 TSRMLS_CC); } elseif_list else_single { zend_do_if_end(TSRMLS_C); } @@ -478,7 +477,7 @@ 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); } | variable '=' expr { zend_check_writable_variable(&$$); zend_do_end_variable_parse(BP_VAR_W, 0 TSRMLS_CC); zend_do_assign(&$$, &$1, &$3 TSRMLS_CC); } - | variable '=' '&' w_variable { zend_check_writable_variable(&$$); zend_do_end_variable_parse(BP_VAR_W, 0 TSRMLS_CC); zend_do_assign_ref(&$$, &$1, &$4 TSRMLS_CC); } + | variable '=' '&' variable { zend_do_end_variable_parse(BP_VAR_W, 0 TSRMLS_CC); zend_do_end_variable_parse(BP_VAR_W, 0 TSRMLS_CC); zend_do_assign_ref(&$$, &$1, &$4 TSRMLS_CC); } | variable '=' '&' 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);} | variable 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); }