diff options
author | Andi Gutmans <andi@php.net> | 1999-09-29 17:18:36 +0000 |
---|---|---|
committer | Andi Gutmans <andi@php.net> | 1999-09-29 17:18:36 +0000 |
commit | 06d04d15a8c14b90c8a28d9cc8e2000eb51bf277 (patch) | |
tree | 2270bd6332d3b3913c8e88e07f55772429a03e9d /Zend/zend_execute.c | |
parent | 446e5d0fffe571adae92b3f8c5e8dcf55608700f (diff) | |
download | php-git-06d04d15a8c14b90c8a28d9cc8e2000eb51bf277.tar.gz |
- Fix SEND_VAR problem after fetch'ing a variable and not knowing the fetch type
Diffstat (limited to 'Zend/zend_execute.c')
-rw-r--r-- | Zend/zend_execute.c | 46 |
1 files changed, 38 insertions, 8 deletions
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 542a75c1c5..604fdb0702 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -69,6 +69,13 @@ static void zend_extension_fcall_begin_handler(zend_extension *extension, zend_o static void zend_extension_fcall_end_handler(zend_extension *extension, zend_op_array *op_array); +#define ARG_SHOULD_BE_SENT_BY_REF(offset) \ + (function_being_called \ + && function_being_called->common.arg_types \ + && offset<=function_being_called->common.arg_types[0] \ + && function_being_called->common.arg_types[offset]==BYREF_FORCE) + + static inline zval *_get_zval_ptr(znode *node, temp_variable *Ts, int *should_free ELS_DC) { switch(node->op_type) { @@ -1151,6 +1158,16 @@ binary_assign_op_addr: { case ZEND_FETCH_RW: zend_fetch_var_address(&opline->result, &opline->op1, &opline->op2, Ts, BP_VAR_RW ELS_CC); break; + case ZEND_FETCH_FUNC_ARG: + if (ARG_SHOULD_BE_SENT_BY_REF(opline->extended_value)) { + /* Behave like FETCH_W */ + zend_fetch_var_address(&opline->result, &opline->op1, &opline->op2, Ts, BP_VAR_W ELS_CC); + } else { + /* Behave like FETCH_R */ + zend_fetch_var_address(&opline->result, &opline->op1, &opline->op2, Ts, BP_VAR_R ELS_CC); + AI_USE_PTR(Ts[opline->result.u.var].var); + } + break; case ZEND_FETCH_IS: zend_fetch_var_address(&opline->result, &opline->op1, &opline->op2, Ts, BP_VAR_IS ELS_CC); break; @@ -1170,6 +1187,16 @@ binary_assign_op_addr: { case ZEND_FETCH_DIM_IS: zend_fetch_dimension_address(&opline->result, &opline->op1, &opline->op2, Ts, BP_VAR_IS ELS_CC); break; + case ZEND_FETCH_DIM_FUNC_ARG: + if (ARG_SHOULD_BE_SENT_BY_REF(opline->extended_value)) { + /* Behave like FETCH_DIM_W */ + zend_fetch_dimension_address(&opline->result, &opline->op1, &opline->op2, Ts, BP_VAR_W ELS_CC); + } else { + /* Behave like FETCH_DIM_R, except for locking used for list() */ + zend_fetch_dimension_address(&opline->result, &opline->op1, &opline->op2, Ts, BP_VAR_R ELS_CC); + AI_USE_PTR(Ts[opline->result.u.var].var); + } + break; case ZEND_FETCH_OBJ_R: zend_fetch_property_address(&opline->result, &opline->op1, &opline->op2, Ts, BP_VAR_R ELS_CC); AI_USE_PTR(Ts[opline->result.u.var].var); @@ -1183,6 +1210,15 @@ binary_assign_op_addr: { case ZEND_FETCH_OBJ_IS: zend_fetch_property_address(&opline->result, &opline->op1, &opline->op2, Ts, BP_VAR_IS ELS_CC); break; + case ZEND_FETCH_OBJ_FUNC_ARG: + if (ARG_SHOULD_BE_SENT_BY_REF(opline->extended_value)) { + /* Behave like FETCH_OBJ_W */ + zend_fetch_property_address(&opline->result, &opline->op1, &opline->op2, Ts, BP_VAR_W ELS_CC); + } else { + zend_fetch_property_address(&opline->result, &opline->op1, &opline->op2, Ts, BP_VAR_R ELS_CC); + AI_USE_PTR(Ts[opline->result.u.var].var); + } + break; case ZEND_FETCH_DIM_TMP_VAR: zend_fetch_dimension_address_from_tmp_var(&opline->result, &opline->op1, &opline->op2, Ts ELS_CC); AI_USE_PTR(Ts[opline->result.u.var].var); @@ -1532,10 +1568,7 @@ do_fcall_common: break; case ZEND_SEND_VAL: if (opline->extended_value==ZEND_DO_FCALL_BY_NAME - && function_being_called - && function_being_called->common.arg_types - && opline->op2.u.opline_num<=function_being_called->common.arg_types[0] - && function_being_called->common.arg_types[opline->op2.u.opline_num]==BYREF_FORCE) { + && ARG_SHOULD_BE_SENT_BY_REF(opline->op2.u.opline_num)) { zend_error(E_ERROR, "Cannot pass parameter %d by reference", opline->op2.u.opline_num); } { @@ -1548,10 +1581,7 @@ do_fcall_common: break; case ZEND_SEND_VAR: if (opline->extended_value==ZEND_DO_FCALL_BY_NAME - && function_being_called - && function_being_called->common.arg_types - && opline->op2.u.opline_num<=function_being_called->common.arg_types[0] - && function_being_called->common.arg_types[opline->op2.u.opline_num]==BYREF_FORCE) { + && ARG_SHOULD_BE_SENT_BY_REF(opline->op2.u.opline_num)) { goto send_by_ref; } { |