Fix nullsafe operator on reference

Dereference the value before checking the type. As the happy path
necessarily has to check for references, I'm not bothering to
delay the comparison.
This commit is contained in:
Nikita Popov 2020-08-11 15:11:36 +02:00
parent 75baa729f5
commit f491dabe40
3 changed files with 27 additions and 0 deletions

View File

@ -0,0 +1,18 @@
--TEST--
Nullsafe operator on referenced value
--FILE--
<?php
$val = null;
$ref =& $val;
var_dump($ref?->foo);
$val = new stdClass;
var_dump($ref?->foo);
?>
--EXPECTF--
NULL
Warning: Undefined property: stdClass::$foo in %s on line %d
NULL

View File

@ -7325,6 +7325,9 @@ ZEND_VM_HOT_NOCONST_HANDLER(198, ZEND_JMP_NULL, CONST|TMPVARCV, JMP_ADDR)
zval *val;
val = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
if (OP1_TYPE != IS_CONST) {
ZVAL_DEREF(val);
}
if (Z_TYPE_INFO_P(val) > IS_NULL) {
ZEND_VM_NEXT_OPCODE();

View File

@ -4375,6 +4375,9 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_NULL_SPEC_CON
zval *val;
val = RT_CONSTANT(opline, opline->op1);
if (IS_CONST != IS_CONST) {
ZVAL_DEREF(val);
}
if (Z_TYPE_INFO_P(val) > IS_NULL) {
ZEND_VM_NEXT_OPCODE();
@ -11095,6 +11098,9 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_NULL_SPEC_TMPV
zval *val;
val = EX_VAR(opline->op1.var);
if ((IS_TMP_VAR|IS_VAR|IS_CV) != IS_CONST) {
ZVAL_DEREF(val);
}
if (Z_TYPE_INFO_P(val) > IS_NULL) {
ZEND_VM_NEXT_OPCODE();