]> granicus.if.org Git - php/commitdiff
Fixed bug #79828
authorNikita Popov <nikita.ppv@gmail.com>
Mon, 13 Jul 2020 07:55:13 +0000 (09:55 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Mon, 13 Jul 2020 07:55:13 +0000 (09:55 +0200)
NEWS
Zend/tests/bug79828.phpt [new file with mode: 0644]
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

diff --git a/NEWS b/NEWS
index 1d7e8885d99ec9559080b2ab6f19fc34398ecc94..222789cf0128f15c7be5bedd3baebc791ed47b8a 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,8 @@ PHP                                                                        NEWS
     op). (Nikita)
   . Fixed bug #79841 (Syntax error in configure / unescaped "[]" in php.m4).
     (Nikita)
+  . Fixed bug #79828 (Segfault when trying to access non-existing variable).
+    (Nikita)
 
 09 Jul 2020, PHP 8.0.0alpha2
 
diff --git a/Zend/tests/bug79828.phpt b/Zend/tests/bug79828.phpt
new file mode 100644 (file)
index 0000000..2bcb18e
--- /dev/null
@@ -0,0 +1,17 @@
+--TEST--
+Bug #79828: Segfault when trying to access non-existing variable
+--FILE--
+<?php
+function foo(): AnyType {
+   return $uninitialized;
+}
+foo();
+?>
+--EXPECTF--
+Warning: Undefined variable $uninitialized in %s on line %d
+
+Fatal error: Uncaught TypeError: foo(): Return value must be of type AnyType, null returned in %s:%d
+Stack trace:
+#0 %s(%d): foo()
+#1 {main}
+  thrown in %s on line %d
index 550a251cac3b1c75587609515b0161b334a40eb3..10266f479222f915b0c4565d007606b35a990930 100644 (file)
@@ -4126,7 +4126,7 @@ ZEND_VM_COLD_CONST_HANDLER(124, ZEND_VERIFY_RETURN_TYPE, CONST|TMP|VAR|UNUSED|CV
 #if !ZEND_VM_SPEC || (OP1_TYPE != IS_UNUSED)
                zval *retval_ref, *retval_ptr;
                zend_arg_info *ret_info = EX(func)->common.arg_info - 1;
-               retval_ref = retval_ptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
+               retval_ref = retval_ptr = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
 
                if (OP1_TYPE == IS_CONST) {
                        ZVAL_COPY(EX_VAR(opline->result.var), retval_ptr);
@@ -4144,6 +4144,14 @@ ZEND_VM_COLD_CONST_HANDLER(124, ZEND_VERIFY_RETURN_TYPE, CONST|TMP|VAR|UNUSED|CV
                        ZEND_VM_NEXT_OPCODE();
                }
 
+               if (OP1_TYPE == IS_CV && UNEXPECTED(Z_ISUNDEF_P(retval_ptr))) {
+                       SAVE_OPLINE();
+                       retval_ref = retval_ptr = ZVAL_UNDEFINED_OP1();
+                       if (ZEND_TYPE_FULL_MASK(ret_info->type) & MAY_BE_NULL) {
+                               ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+                       }
+               }
+
                zend_reference *ref = NULL;
                void *cache_slot = CACHE_ADDR(opline->op2.num);
                if (UNEXPECTED(retval_ref != retval_ptr)) {
index 5dcd4812e939c1998472df4e4e0a8c48e4c6a125..de4b37e9c37b9fccf943d369d2a6bbb953350de0 100644 (file)
@@ -8825,6 +8825,14 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYP
                        ZEND_VM_NEXT_OPCODE();
                }
 
+               if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(retval_ptr))) {
+                       SAVE_OPLINE();
+                       retval_ref = retval_ptr = ZVAL_UNDEFINED_OP1();
+                       if (ZEND_TYPE_FULL_MASK(ret_info->type) & MAY_BE_NULL) {
+                               ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+                       }
+               }
+
                zend_reference *ref = NULL;
                void *cache_slot = CACHE_ADDR(opline->op2.num);
                if (UNEXPECTED(retval_ref != retval_ptr)) {
@@ -18934,6 +18942,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_TMP_UN
                        ZEND_VM_NEXT_OPCODE();
                }
 
+               if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(retval_ptr))) {
+                       SAVE_OPLINE();
+                       retval_ref = retval_ptr = ZVAL_UNDEFINED_OP1();
+                       if (ZEND_TYPE_FULL_MASK(ret_info->type) & MAY_BE_NULL) {
+                               ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+                       }
+               }
+
                zend_reference *ref = NULL;
                void *cache_slot = CACHE_ADDR(opline->op2.num);
                if (UNEXPECTED(retval_ref != retval_ptr)) {
@@ -26456,6 +26472,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_VAR_UN
                        ZEND_VM_NEXT_OPCODE();
                }
 
+               if (IS_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(retval_ptr))) {
+                       SAVE_OPLINE();
+                       retval_ref = retval_ptr = ZVAL_UNDEFINED_OP1();
+                       if (ZEND_TYPE_FULL_MASK(ret_info->type) & MAY_BE_NULL) {
+                               ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+                       }
+               }
+
                zend_reference *ref = NULL;
                void *cache_slot = CACHE_ADDR(opline->op2.num);
                if (UNEXPECTED(retval_ref != retval_ptr)) {
@@ -33176,6 +33200,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_UNUSED
                        ZEND_VM_NEXT_OPCODE();
                }
 
+               if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(retval_ptr))) {
+                       SAVE_OPLINE();
+                       retval_ref = retval_ptr = ZVAL_UNDEFINED_OP1();
+                       if (ZEND_TYPE_FULL_MASK(ret_info->type) & MAY_BE_NULL) {
+                               ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+                       }
+               }
+
                zend_reference *ref = NULL;
                void *cache_slot = CACHE_ADDR(opline->op2.num);
                if (UNEXPECTED(retval_ref != retval_ptr)) {
@@ -44739,7 +44771,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_CV_UNU
 #if 0 || (IS_CV != IS_UNUSED)
                zval *retval_ref, *retval_ptr;
                zend_arg_info *ret_info = EX(func)->common.arg_info - 1;
-               retval_ref = retval_ptr = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
+               retval_ref = retval_ptr = EX_VAR(opline->op1.var);
 
                if (IS_CV == IS_CONST) {
                        ZVAL_COPY(EX_VAR(opline->result.var), retval_ptr);
@@ -44757,6 +44789,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_CV_UNU
                        ZEND_VM_NEXT_OPCODE();
                }
 
+               if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(retval_ptr))) {
+                       SAVE_OPLINE();
+                       retval_ref = retval_ptr = ZVAL_UNDEFINED_OP1();
+                       if (ZEND_TYPE_FULL_MASK(ret_info->type) & MAY_BE_NULL) {
+                               ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+                       }
+               }
+
                zend_reference *ref = NULL;
                void *cache_slot = CACHE_ADDR(opline->op2.num);
                if (UNEXPECTED(retval_ref != retval_ptr)) {