Skip to content

Commit 15d1d4f

Browse files
committed
Fixed bug #72038 (Function calls with values to a by-ref parameter don't always throw a notice)
1 parent 02766d0 commit 15d1d4f

File tree

6 files changed

+61
-33
lines changed

6 files changed

+61
-33
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ PHP NEWS
22
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
33
?? ??? 2016 PHP 7.0.7
44

5+
- Core:
6+
. Fixed Bug #72038 (Function calls with values to a by-ref parameter don't
7+
always throw a notice). (Bob)
8+
59
- OCI8:
610
. Fixed bug #71600 (oci_fetch_all segfaults when selecting more than eight
711
columns). (Tian Yang)

Zend/tests/bug34617.phpt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ class Thing {}
88
function boom()
99
{
1010
$reader = xml_parser_create();
11-
xml_set_object($reader, new Thing());
11+
$thing = new Thing();
12+
xml_set_object($reader, $thing);
1213
die("ok\n");
1314
xml_parser_free($reader);
1415
}

Zend/tests/bug72038.phpt

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
--TEST--
2+
Bug #72038 (Function calls with values to a by-ref parameter don't always throw a notice)
3+
--FILE--
4+
<?php
5+
6+
test($foo = new stdClass);
7+
var_dump($foo);
8+
test($bar = 2);
9+
var_dump($bar);
10+
test($baz = &$bar);
11+
var_dump($baz);
12+
13+
function test(&$param) {
14+
$param = 1;
15+
}
16+
17+
?>
18+
--EXPECTF--
19+
20+
Notice: Only variables should be passed by reference in %s on line %d
21+
object(stdClass)#1 (0) {
22+
}
23+
24+
Notice: Only variables should be passed by reference in %s on line %d
25+
int(2)
26+
int(1)
27+

Zend/tests/each_002.phpt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@ Testing each() with array and object
33
--FILE--
44
<?php
55

6-
$foo = each(new stdClass);
6+
$a = new stdClass;
7+
$foo = each($a);
78
var_dump($foo);
89

9-
var_dump(each(new stdClass));
10+
$a = new stdClass;
11+
var_dump(each($a));
1012

1113
$a = array(new stdClass);
1214
var_dump(each($a));

Zend/zend_vm_def.h

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4299,27 +4299,24 @@ ZEND_VM_HANDLER(106, ZEND_SEND_VAR_NO_REF, VAR, ANY)
42994299

43004300
varptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
43014301

4302-
if ((!(opline->extended_value & ZEND_ARG_SEND_FUNCTION) ||
4303-
(Z_VAR_FLAGS_P(varptr) & IS_VAR_RET_REF)) &&
4304-
(Z_ISREF_P(varptr) || Z_TYPE_P(varptr) == IS_OBJECT)) {
4302+
if (EXPECTED(Z_ISREF_P(varptr) ||
4303+
((opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) ?
4304+
(opline->extended_value & ZEND_ARG_SEND_SILENT) :
4305+
ARG_MAY_BE_SENT_BY_REF(EX(call)->func, opline->op2.num
4306+
)))) {
4307+
arg = ZEND_CALL_VAR(EX(call), opline->result.var);
4308+
ZVAL_COPY_VALUE(arg, varptr);
43054309

4306-
ZVAL_MAKE_REF(varptr);
4307-
} else {
4308-
if ((opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) ?
4309-
!(opline->extended_value & ZEND_ARG_SEND_SILENT) :
4310-
!ARG_MAY_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) {
4311-
SAVE_OPLINE();
4312-
zend_error(E_NOTICE, "Only variables should be passed by reference");
4313-
arg = ZEND_CALL_VAR(EX(call), opline->result.var);
4314-
ZVAL_COPY_VALUE(arg, varptr);
4315-
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
4316-
}
4310+
ZEND_VM_NEXT_OPCODE();
43174311
}
43184312

4313+
SAVE_OPLINE();
4314+
zend_error(E_NOTICE, "Only variables should be passed by reference");
4315+
43194316
arg = ZEND_CALL_VAR(EX(call), opline->result.var);
43204317
ZVAL_COPY_VALUE(arg, varptr);
43214318

4322-
ZEND_VM_NEXT_OPCODE();
4319+
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
43234320
}
43244321

43254322
ZEND_VM_HANDLER(67, ZEND_SEND_REF, VAR|CV, ANY)

Zend/zend_vm_execute.h

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15237,27 +15237,24 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_SPEC_VAR_HANDL
1523715237

1523815238
varptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
1523915239

15240-
if ((!(opline->extended_value & ZEND_ARG_SEND_FUNCTION) ||
15241-
(Z_VAR_FLAGS_P(varptr) & IS_VAR_RET_REF)) &&
15242-
(Z_ISREF_P(varptr) || Z_TYPE_P(varptr) == IS_OBJECT)) {
15240+
if (EXPECTED(Z_ISREF_P(varptr) ||
15241+
((opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) ?
15242+
(opline->extended_value & ZEND_ARG_SEND_SILENT) :
15243+
ARG_MAY_BE_SENT_BY_REF(EX(call)->func, opline->op2.num
15244+
)))) {
15245+
arg = ZEND_CALL_VAR(EX(call), opline->result.var);
15246+
ZVAL_COPY_VALUE(arg, varptr);
1524315247

15244-
ZVAL_MAKE_REF(varptr);
15245-
} else {
15246-
if ((opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) ?
15247-
!(opline->extended_value & ZEND_ARG_SEND_SILENT) :
15248-
!ARG_MAY_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) {
15249-
SAVE_OPLINE();
15250-
zend_error(E_NOTICE, "Only variables should be passed by reference");
15251-
arg = ZEND_CALL_VAR(EX(call), opline->result.var);
15252-
ZVAL_COPY_VALUE(arg, varptr);
15253-
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
15254-
}
15248+
ZEND_VM_NEXT_OPCODE();
1525515249
}
1525615250

15251+
SAVE_OPLINE();
15252+
zend_error(E_NOTICE, "Only variables should be passed by reference");
15253+
1525715254
arg = ZEND_CALL_VAR(EX(call), opline->result.var);
1525815255
ZVAL_COPY_VALUE(arg, varptr);
1525915256

15260-
ZEND_VM_NEXT_OPCODE();
15257+
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1526115258
}
1526215259

1526315260
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)

0 commit comments

Comments
 (0)