]> granicus.if.org Git - php/commitdiff
Fix nullsafe operator on reference
authorNikita Popov <nikita.ppv@gmail.com>
Tue, 11 Aug 2020 13:11:36 +0000 (15:11 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Tue, 11 Aug 2020 13:11:36 +0000 (15:11 +0200)
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.

Zend/tests/nullsafe_operator/031.phpt [new file with mode: 0644]
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

diff --git a/Zend/tests/nullsafe_operator/031.phpt b/Zend/tests/nullsafe_operator/031.phpt
new file mode 100644 (file)
index 0000000..5d287ce
--- /dev/null
@@ -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
index c5583feb6681135c01a3ecdd0dd2714bce19ea1d..f06713d5ac8abfbf835111d6dd19e768454a62ba 100644 (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();
index b9ccb2226cc0df487e49c2af05ecddce1463b2a1..e564ec3c18ab69e3feccd62852466c0d49a3a473 100644 (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();