From: Dmitry Stogov Date: Tue, 26 Sep 2006 10:31:04 +0000 (+0000) Subject: Fixed bug #38808 ("maybe ref" issue for current() and others) X-Git-Tag: RELEASE_1_0_0RC1~1543 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=798d93c4daa3f417314e1107124bc820ae73bdfc;p=php Fixed bug #38808 ("maybe ref" issue for current() and others) --- diff --git a/Zend/tests/bug38808.phpt b/Zend/tests/bug38808.phpt new file mode 100755 index 0000000000..0fc4bfecdc --- /dev/null +++ b/Zend/tests/bug38808.phpt @@ -0,0 +1,17 @@ +--TEST-- +Bug #38808 ("maybe ref" issue for current() and others) +--FILE-- +'one', 2=>'two'); +$a =& $b; + +echo $current($a)."\n"; +$next($a); +echo $current($a)."\n"; +?> +--EXPECT-- +one +two \ No newline at end of file diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 6dc24704ef..df0bf24c6a 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -691,40 +691,23 @@ int zendlex(znode *zendlval TSRMLS_DC); #define ZEND_SEND_BY_REF 1 #define ZEND_SEND_PREFER_REF 2 -/* Lost In Stupid Parentheses */ -#define ARG_SHOULD_BE_SENT_BY_REF(zf, arg_num) \ - ( \ - zf \ - && ((zend_function *) zf)->common.arg_info \ - && \ - ( \ - ( \ - arg_num<=((zend_function *) zf)->common.num_args \ - && ((zend_function *) zf)->common.arg_info[arg_num-1].pass_by_reference == ZEND_SEND_BY_REF \ - ) \ - || ( \ - arg_num>((zend_function *) zf)->common.num_args \ - && ((zend_function *) zf)->common.pass_rest_by_reference == ZEND_SEND_BY_REF \ - ) \ - ) \ - ) - -#define ARG_MAY_BE_SENT_BY_REF(zf, arg_num) \ - ( \ - zf \ - && ((zend_function *) zf)->common.arg_info \ - && \ - ( \ - ( \ - arg_num<=((zend_function *) zf)->common.num_args \ - && ((zend_function *) zf)->common.arg_info[arg_num-1].pass_by_reference == ZEND_SEND_PREFER_REF \ - ) \ - || ( \ - arg_num>((zend_function *) zf)->common.num_args \ - && ((zend_function *) zf)->common.pass_rest_by_reference == ZEND_SEND_PREFER_REF \ - ) \ - ) \ - ) +#define ARG_SEND_TYPE(zf, arg_num) \ + ((zf) ? \ + ((((zend_function*)(zf))->common.arg_info && \ + arg_num<=((zend_function*)(zf))->common.num_args) ? \ + ((zend_function *)(zf))->common.arg_info[arg_num-1].pass_by_reference : \ + ((zend_function *)(zf))->common.pass_rest_by_reference) : \ + ZEND_SEND_BY_VAL) + +#define ARG_MUST_BE_SENT_BY_REF(zf, arg_num) \ + (ARG_SEND_TYPE(zf, arg_num) == ZEND_SEND_BY_REF) + +#define ARG_SHOULD_BE_SENT_BY_REF(zf, arg_num) \ + (ARG_SEND_TYPE(zf, arg_num) & (ZEND_SEND_BY_REF|ZEND_SEND_PREFER_REF)) + +#define ARG_MAY_BE_SENT_BY_REF(zf, arg_num) \ + (ARG_SEND_TYPE(zf, arg_num) == ZEND_SEND_PREFER_REF) + #define ZEND_RETURN_VAL 0 #define ZEND_RETURN_REF 1 diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 9fcd1284aa..dca5b9c56e 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -2202,7 +2202,7 @@ ZEND_VM_HANDLER(65, ZEND_SEND_VAL, CONST|TMP|VAR|CV, ANY) { zend_op *opline = EX(opline); if (opline->extended_value==ZEND_DO_FCALL_BY_NAME - && ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) { + && ARG_MUST_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) { zend_error_noreturn(E_ERROR, "Cannot pass parameter %d by reference", opline->op2.u.opline_num); } { diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index d2afe00271..99277f2b18 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -1744,7 +1744,7 @@ static int ZEND_SEND_VAL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zend_op *opline = EX(opline); if (opline->extended_value==ZEND_DO_FCALL_BY_NAME - && ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) { + && ARG_MUST_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) { zend_error_noreturn(E_ERROR, "Cannot pass parameter %d by reference", opline->op2.u.opline_num); } { @@ -4338,7 +4338,7 @@ static int ZEND_SEND_VAL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zend_op *opline = EX(opline); if (opline->extended_value==ZEND_DO_FCALL_BY_NAME - && ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) { + && ARG_MUST_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) { zend_error_noreturn(E_ERROR, "Cannot pass parameter %d by reference", opline->op2.u.opline_num); } { @@ -7439,7 +7439,7 @@ static int ZEND_SEND_VAL_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zend_op *opline = EX(opline); if (opline->extended_value==ZEND_DO_FCALL_BY_NAME - && ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) { + && ARG_MUST_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) { zend_error_noreturn(E_ERROR, "Cannot pass parameter %d by reference", opline->op2.u.opline_num); } { @@ -19980,7 +19980,7 @@ static int ZEND_SEND_VAL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zend_op *opline = EX(opline); if (opline->extended_value==ZEND_DO_FCALL_BY_NAME - && ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) { + && ARG_MUST_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) { zend_error_noreturn(E_ERROR, "Cannot pass parameter %d by reference", opline->op2.u.opline_num); } {